# Contoh Implementasi PHP - Penerimaan Pembayaran

Dokumentasi lengkap dengan contoh kode PHP untuk mengintegrasikan fitur penerimaan pembayaran (pay-in).

## Class PaymentCollectorAPI

```php
<?php
class PaymentCollectorAPI {
    
    private $baseUrl = "https://pay-test.targeted.work/";
    private $memberId = "10036";
    private $secretKey = "150kz9esh1s2f793abb8l0e4mjot3r2c";
    
    /**
     * Generate MD5 Signature
     */
    public function generateSignature($data) {
        ksort($data);
        
        $stringSignTemp = "";
        foreach ($data as $key => $value) {
            if (!empty($value)) {
                $stringSignTemp .= $key . "=" . $value . "&";
            }
        }
        
        $stringSignTemp .= "key=" . $this->secretKey;
        return strtoupper(md5($stringSignTemp));
    }
    
    /**
     * Send Request via cURL
     */
    private function sendRequest($endpoint, $data) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->baseUrl . $endpoint);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
    
    /**
     * Request Payment (Non-Counter)
     */
    public function requestPayment($params) {
        $data = [
            "memberId" => $this->memberId,
            "orderId" => $params['orderId'],
            "amount" => $params['amount'],
            "dstCode" => $params['dstCode'],
            "name" => $params['name'],
            "phone" => $params['phone'],
            "email" => $params['email'],
            "notifyUrl" => $params['notifyUrl'],
            "dateTime" => date("Y-m-d H:i:s")
        ];
        
        if (!empty($params['remark'])) {
            $data['remark'] = $params['remark'];
        }
        
        $data['sign'] = $this->generateSignature($data);
        
        $response = $this->sendRequest("pay.html", $data);
        return json_decode($response, true);
    }
    
    /**
     * Request Payment with Counter (Kasir)
     */
    public function requestPaymentWithCounter($params) {
        $data = [
            "memberId" => $this->memberId,
            "orderId" => $params['orderId'],
            "amount" => $params['amount'],
            "dstCode" => $params['dstCode'],
            "name" => $params['name'],
            "phone" => $params['phone'],
            "email" => $params['email'],
            "notifyUrl" => $params['notifyUrl'],
            "dateTime" => date("Y-m-d H:i:s")
        ];
        
        if (!empty($params['remark'])) {
            $data['remark'] = $params['remark'];
        }
        
        $data['sign'] = $this->generateSignature($data);
        
        $response = $this->sendRequest("pay_counter.html", $data);
        return json_decode($response, true);
    }
    
    /**
     * Query Order Status
     */
    public function queryOrderStatus($orderId) {
        $data = [
            "memberId" => $this->memberId,
            "orderId" => $orderId
        ];
        
        $data['sign'] = $this->generateSignature($data);
        
        $response = $this->sendRequest("pay_trade_query.html", $data);
        return json_decode($response, true);
    }
    
    /**
     * Verify Callback Signature
     */
    public function verifyCallbackSignature($callbackData) {
        $sign = $callbackData['sign'];
        unset($callbackData['sign']);
        
        $calculatedSign = $this->generateSignature($callbackData);
        return strtoupper($sign) === strtoupper($calculatedSign);
    }
    
    /**
     * Handle Callback
     */
    public function handleCallback($callbackData) {
        // Verify signature
        if (!$this->verifyCallbackSignature($callbackData)) {
            return ['status' => 'error', 'msg' => 'Invalid signature'];
        }
        
        $orderId = $callbackData['orderId'];
        $refCode = $callbackData['refCode'];
        
        // Update database
        if ($refCode == '1') {
            // Payment success
            updateOrderStatus($orderId, 'PAID', $callbackData);
        } else {
            // Payment failed
            updateOrderStatus($orderId, 'FAILED', $callbackData);
        }
        
        return ['status' => 'success', 'msg' => 'Callback processed'];
    }
}
?>
```

## Contoh Penggunaan

### 1. Request Payment dengan Bank VA (Non-Counter)

```php
<?php
require 'PaymentCollectorAPI.php';

$api = new PaymentCollectorAPI();

$params = [
    'orderId' => 'ORDER-' . time(),
    'amount' => 50000,
    'dstCode' => 'PERMATA',
    'name' => 'John Doe',
    'phone' => '08123456789',
    'email' => 'john@example.com',
    'notifyUrl' => 'https://yoursite.com/callback.php',
    'remark' => 'Order for product X'
];

$result = $api->requestPayment($params);

if ($result['status'] == 'success') {
    $data = $result['data'];
    echo "Order ID: " . $data['orderId'];
    echo "Bank: " . $data['bankName'];
    echo "Account: " . $data['account'];
    echo "Amount: Rp " . number_format($data['totalAmount']);
    echo "Expire: " . $data['expireTime'];
} else {
    echo "Error: " . $result['msg'];
}
?>
```

### 2. Request Payment dengan OVO Counter (Kasir)

```php
<?php
require 'PaymentCollectorAPI.php';

$api = new PaymentCollectorAPI();

$params = [
    'orderId' => 'ORDER-' . time(),
    'amount' => 50000,
    'dstCode' => 'OVO',
    'name' => 'John Doe',
    'phone' => '08123456789',
    'email' => 'john@example.com',
    'notifyUrl' => 'https://yoursite.com/callback.php'
];

$result = $api->requestPaymentWithCounter($params);

if ($result['status'] == 'success') {
    // Redirect ke payment gateway
    header("Location: " . $result['data']['redirectUrl']);
    exit;
} else {
    echo "Error: " . $result['msg'];
}
?>
```

### 3. Query Order Status

```php
<?php
require 'PaymentCollectorAPI.php';

$api = new PaymentCollectorAPI();

$orderId = 'ORDER-123456';
$result = $api->queryOrderStatus($orderId);

if ($result['status'] == 'success') {
    $status = $result['data']['status'];
    if ($status == '1') {
        echo "Payment successful at " . $result['data']['successTime'];
    } else if ($status == '0') {
        echo "Payment pending";
    } else if ($status == '2') {
        echo "Payment failed";
    }
} else {
    echo "Error: " . $result['msg'];
}
?>
```

### 4. Handle Callback

```php
<?php
// callback.php
require 'PaymentCollectorAPI.php';

$api = new PaymentCollectorAPI();

// Receive callback data
$callbackData = $_POST;

// Verify and process
$result = $api->handleCallback($callbackData);

if ($result['status'] == 'success') {
    echo "OK";
} else {
    exit;
}
?>
```

## Helper Functions

```php
<?php
function updateOrderStatus($orderId, $status, $data) {
    $mysqli = new mysqli("localhost", "user", "password", "database");
    
    $query = "UPDATE orders SET status = ?, paid_amount = ?, paid_time = ?, bank = ?, account = ? WHERE order_id = ?";
    $stmt = $mysqli->prepare($query);
    
    $stmt->bind_param(
        "ssisss",
        $status,
        $data['amount'],
        $data['paidTime'] ?? date("Y-m-d H:i:s"),
        $data['bankName'] ?? $data['dstCode'],
        $data['account'],
        $orderId
    );
    
    return $stmt->execute();
}

function sendPaymentConfirmationEmail($email, $orderData) {
    $subject = "Pembayaran Berhasil - Order #" . $orderData['orderId'];
    $message = "Terima kasih atas pembayaran Anda.\n\n";
    $message .= "Order ID: " . $orderData['orderId'] . "\n";
    $message .= "Amount: Rp " . number_format($orderData['amount']) . "\n";
    $message .= "Status: PAID\n";
    
    mail($email, $subject, $message);
}
?>
```

---

**Catatan**: Pastikan callback.php dapat diakses dari internet dan menggunakan HTTPS untuk keamanan.
