### PHP Callback Handler Example Source: https://myiskapay.com/api/docs A practical example of a PHP handler to process incoming payment completion callbacks, including signature verification and status checking. ```APIDOC ## PHP Callback Handler Example ### Handler Implementation This example demonstrates how to implement a callback handler in PHP, ensuring signature verification and proper business logic execution. ```php 'Invalid signature'])); } // 2. Process only if payment status is 'paid' if ($payload['payment']['status'] === 'paid') { $orderId = $payload['payment']['merchant_order_id']; $amount = (int) $payload['payment']['amount']; // Cast to int for business logic // Implement idempotency check (prevent duplicate processing) // if (already_processed($orderId)) { ... } // Update order status in your database // update_order($orderId, 'paid', $amount); } // 3. Respond with HTTP 200 to prevent retries http_response_code(200); echo json_encode(['status' => 'ok']); ?> ``` ``` -------------------------------- ### Node.js Callback Handler Example Source: https://myiskapay.com/api/docs An example of a Node.js handler for processing Iskpay callbacks, including signature verification and conditional processing. ```APIDOC ## Node.js Callback Handler Example ### Handler Implementation This Node.js example shows how to handle callbacks, verify signatures, and process payments. ```javascript const crypto = require('crypto'); app.post('/callback', (req, res) => { const { payment, signature } = req.body; // 1. Verify signature - use raw values, do not parse integers const expected = crypto.createHash('sha256') .update(String(payment.merchant_order_id) + String(payment.status) + String(payment.amount) + // 50000 -> "50000" String(payment.id)) .digest('hex'); if (expected !== signature) { return res.status(401).json({ error: 'Invalid signature' }); } // 2. Process only if payment is 'paid' if (payment.status === 'paid') { // Update order in your database // Example: updateOrder(payment.merchant_order_id, 'paid', payment.amount); } // 3. Respond with 200 OK res.json({ status: 'ok' }); }); ``` ``` -------------------------------- ### Get API Key Information Source: https://myiskapay.com/api/docs.json Provides details about the API key, including its name, permissions, usage statistics, and expiration. ```APIDOC ## GET /api/gateway/api-key ### Description Info dan statistik pemakaian API key ### Method GET ### Endpoint /api/gateway/api-key ### Response #### Success Response (200) - **name** (string) - Description - **permissions** (array) - Description - **usage_count** (integer) - Description - **rate_limit** (integer) - Description - **remaining_usage** (integer) - Description - **last_used_at** (string) - Description - **expires_at** (string) - Description ``` -------------------------------- ### Callback Handler Example (PHP) Source: https://myiskapay.com/api/docs A complete PHP handler for processing payment callbacks. It includes signature verification, status checking for 'paid' orders, and idempotency considerations. Responds with HTTP 200 to prevent retries. ```php $payload = json_decode(file_get_contents('php://input'), true); // 1. Verifikasi signature — gunakan raw value dari payload, jangan cast $expected = hash('sha256', $payload['payment']['merchant_order_id'] . $payload['payment']['status'] . $payload['payment']['amount'] . // integer 50000, concat jadi "50000" $payload['payment']['id'] ); if ($expected !== $payload['signature']) { http_response_code(401); exit(json_encode(['error' => 'Invalid signature'])); } // 2. Cek status — hanya proses jika paid if ($payload['payment']['status'] === 'paid') { $orderId = $payload['payment']['merchant_order_id']; $amount = (int) $payload['payment']['amount']; // cast ke int untuk logika bisnis // Cek idempotency (jangan proses duplikat) // if (already_processed($orderId)) { ... } // Update order di database Anda // update_order($orderId, 'paid', $amount); } // 3. Response 200 agar tidak di-retry http_response_code(200); echo json_encode(['status' => 'ok']); ``` -------------------------------- ### Get User Information Source: https://myiskapay.com/api/docs.json Fetches detailed information about the user account associated with the API key. Includes user profile and account status. ```APIDOC ## GET /api/gateway/user ### Description Informasi akun user ### Method GET ### Endpoint /api/gateway/user ### Response #### Success Response (200) - **id** (integer) - Description - **name** (string) - Description - **email** (string) - Description - **username** (string) - Description - **balance** (number) - Description - **formatted_balance** (string) - Description - **status** (string) - Description - **role** (string) - Description - **created_at** (string) - Description ``` -------------------------------- ### Payment Creation Success Response Source: https://myiskapay.com/api/docs This is an example of a successful response (201 Created) when a payment is created. It includes details like the payment ID, QR code URL, payment URL, and expiration time. Note the 'unique_amount' which is added to the original 'amount'. ```json { "success": true, "message": "Payment created successfully", "data": { "payment_id": 123, "merchant_order_id": "INV-1-20260412143000-AB1C", "amount": 50000, "total_amount": 50123, "unique_amount": 123, "status": "pending", "payment_method": "qris", "qr_code": "https://pg-iskapay.com/storage/qris/abc123.png", "qr_string": "00020101021226680016COM.NOBUBANK.WWW...", "payment_url": "https://myiskapay.com/payment/INV-1-20260412143000-AB1C", "callback_url": "https://yoursite.com/callback", "return_url": "https://yoursite.com/return", "expired_at": "2026-04-12T15:30:00.000000Z", "created_at": "2026-04-12T14:30:00.000000Z" } } ``` -------------------------------- ### Get Account Balance Source: https://myiskapay.com/api/docs.json Retrieves the current balance of the merchant's account. This provides a quick overview of available funds. ```APIDOC ## GET /api/gateway/balance ### Description Ambil saldo akun ### Method GET ### Endpoint /api/gateway/balance ### Response #### Success Response (200) - **balance** (number) - Description - **formatted_balance** (string) - Description - **last_updated** (string) - Description ``` -------------------------------- ### Payment Status Response - Paid Source: https://myiskapay.com/api/docs Example response when a payment has been successfully paid. The 'status' field will be 'paid', and 'paid_at' will contain the timestamp of the payment. 'time_remaining' will be null. ```json { "success": true, "data": { "payment_id": 123, "merchant_order_id": "INV-1-20260412143000-AB1C", "amount": 50000, "total_amount": 50123, "unique_amount": 123, "status": "paid", "payment_method": "qris", "qr_code": "https://pg-iskapay.com/storage/qris/abc123.png", "qr_string": "00020101021226680016COM.NOBUBANK.WWW...", "paid_at": "2026-04-12T14:35:00.000000Z", "expired_at": "2026-04-12T15:30:00.000000Z", "created_at": "2026-04-12T14:30:00.000000Z", "updated_at": "2026-04-12T14:35:00.000000Z", "time_remaining": null, "provider_reference": "callback_1712930100", "return_url": "https://yoursite.com/return" } } ``` -------------------------------- ### Callback Handler Example (Node.js) Source: https://myiskapay.com/api/docs A Node.js handler for processing payment callbacks using Express. It verifies the signature by hashing concatenated fields and checks if the payment status is 'paid' before proceeding. ```javascript const crypto = require('crypto'); app.post('/callback', (req, res) => { const { payment, signature } = req.body; // 1. Verifikasi signature — gunakan raw value, jangan parseInt const expected = crypto.createHash('sha256') .update(String(payment.merchant_order_id) + String(payment.status) + String(payment.amount) + // 50000 -> "50000" String(payment.id)) .digest('hex'); if (expected !== signature) { return res.status(401).json({ error: 'Invalid signature' }); } // 2. Proses hanya jika paid if (payment.status === 'paid') { // Update order di database Anda } // 3. Response 200 res.json({ status: 'ok' }); }); ``` -------------------------------- ### Payment Status Response - Pending Source: https://myiskapay.com/api/docs Example response when a payment is still pending. The 'time_remaining' field provides details on how much time is left before expiration. 'provider_reference' will be null at this stage. ```json { "success": true, "data": { "payment_id": 123, "merchant_order_id": "INV-1-20260412143000-AB1C", "amount": 50000, "total_amount": 50123, "unique_amount": 123, "status": "pending", "payment_method": "qris", "qr_code": "https://pg-iskapay.com/storage/qris/abc123.png", "qr_string": "00020101021226680016COM.NOBUBANK.WWW...", "paid_at": null, "expired_at": "2026-04-12T15:30:00.000000Z", "created_at": "2026-04-12T14:30:00.000000Z", "updated_at": "2026-04-12T14:30:00.000000Z", "time_remaining": { "total_seconds": 3300, "hours": 0, "minutes": 55, "seconds": 0, "is_expired": false, "formatted": "00:55:00" }, "provider_reference": null, "return_url": "https://yoursite.com/return" } } ``` -------------------------------- ### Get Merchant Information Source: https://myiskapay.com/api/docs.json Retrieves information about the active merchant, including their merchant code, name, and allowed payment methods. ```APIDOC ## GET /api/gateway/merchant ### Description Informasi merchant aktif ### Method GET ### Endpoint /api/gateway/merchant ### Response #### Success Response (200) - **merchant_code** (string) - Description - **merchant_name** (string) - Description - **is_active** (boolean) - Description - **allowed_methods** (array) - Description - **created_at** (string) - Description ``` -------------------------------- ### Payment Status Response - Expired Source: https://myiskapay.com/api/docs Example response when a payment has expired. The 'status' field will be 'expired', and 'time_remaining' will be null. This status is automatically updated by the API if the payment is still pending past its 'expired_at' time. ```json { "success": true, "data": { "payment_id": 123, "status": "expired", "time_remaining": null, ... } } ``` -------------------------------- ### Create QRIS Payment with cURL Source: https://myiskapay.com/api/docs Use this cURL command to create a new QRIS payment. Ensure you replace 'your_api_key' with your actual API key and adjust the amount and customer details as needed. The callback_url is essential for receiving payment notifications. ```bash curl -X POST https://myiskapay.com/api/gateway/payments \ -H "Content-Type: application/json" \ -H "X-API-Key: your_api_key" \ -d '{ "amount": 50000, "customer_name": "John Doe", "callback_url": "https://yoursite.com/callback" }' ``` -------------------------------- ### Signature Verification Source: https://myiskapay.com/api/docs Learn how to verify the callback signature using SHA-256 to ensure data integrity and authenticity. ```APIDOC ## Signature Verification ### Verifying the Signature The signature is generated using SHA-256 from a concatenation of four fields: `payment.merchant_order_id`, `payment.status`, `payment.amount`, and `payment.id`. All values are converted to strings before concatenation. **Note:** Use the `amount` field directly as an integer (e.g., `50000`) for concatenation, not as a float or formatted string. ``` // Format: merchant_order_id + status + amount + payment_id // Example: "INV-1-20260412143000-AB1C" + "paid" + "50000" + "123" // Concatenated string: "INV-1-20260412143000-AB1Cpaid50000123" $expected = hash('sha256', $payload['payment']['merchant_order_id'] . $payload['payment']['status'] . $payload['payment']['amount'] . $payload['payment']['id'] ); if ($expected === $payload['signature']) { // Callback is valid } ``` ``` -------------------------------- ### Signature Generation Source: https://myiskapay.com/api/docs.json Details on how to generate the SHA-256 signature for verifying callback authenticity. ```APIDOC ## Signature Generation ### Description Details on how to generate the SHA-256 signature for verifying callback authenticity. ### Algorithm SHA-256 ### Format merchant_order_id + status + amount(integer) + payment_id (concat tanpa separator) ### Example hash("sha256", "INV-1-20260412143000-AB1Cpaid50000123") ### Important Note Amount should be concatenated as an integer string (e.g., "50000"), not a float (e.g., "50000.00"). Use the raw value from the payload without casting. ``` -------------------------------- ### Create Payment Source: https://myiskapay.com/api/docs Use this endpoint to create a new QRIS payment. You can specify payment details such as amount, customer information, and callback URLs. The API will return payment details including a QR code and payment URL. ```APIDOC ## POST /api/gateway/payments ### Description Buat pembayaran QRIS baru. ### Method POST ### Endpoint https://myiskapay.com/api/gateway/payments ### Parameters #### Request Body - **amount** (number) - Required - Nominal pembayaran (min: 2.000, max: 50.000.000) - **customer_name** (string) - Required - Nama customer (max: 100) - **merchant_order_id** (string) - Optional - ID order unik Anda (max: 100). Auto-generated jika kosong. - **payment_method** (string) - Optional - qris | bank_transfer | e_wallet - **customer_email** (string) - Optional - Email customer - **customer_phone** (string) - Optional - Nomor telepon customer - **description** (string) - Optional - Deskripsi pembayaran (max: 255) - **callback_url** (string) - Optional - URL webhook saat pembayaran berhasil - **return_url** (string) - Optional - URL redirect setelah pembayaran - **expired_time** (integer) - Optional - Waktu expired dalam detik (min: 300, max: 86400). Default: 3600 ### Request Example ```json { "amount": 50000, "customer_name": "John Doe", "callback_url": "https://yoursite.com/callback" } ``` ### Response #### Success Response (201) - **success** (boolean) - Indicates if the request was successful. - **message** (string) - A message describing the result of the operation. - **data** (object) - Contains the payment details. - **payment_id** (integer) - The unique identifier for the payment. - **merchant_order_id** (string) - Your unique order ID. - **amount** (number) - The payment amount. - **total_amount** (number) - The total amount including any unique additions. - **unique_amount** (number) - The unique amount added to the payment. - **status** (string) - The current status of the payment (e.g., 'pending'). - **payment_method** (string) - The method used for payment (e.g., 'qris'). - **qr_code** (string) - URL to the QR code image. - **qr_string** (string) - The raw QR code string. - **payment_url** (string) - URL to the payment page. - **callback_url** (string) - The configured callback URL. - **return_url** (string) - The configured return URL. - **expired_at** (string) - The timestamp when the payment expires. - **created_at** (string) - The timestamp when the payment was created. #### Response Example (201) ```json { "success": true, "message": "Payment created successfully", "data": { "payment_id": 123, "merchant_order_id": "INV-1-20260412143000-AB1C", "amount": 50000, "total_amount": 50123, "unique_amount": 123, "status": "pending", "payment_method": "qris", "qr_code": "https://pg-iskapay.com/storage/qris/abc123.png", "qr_string": "00020101021226680016COM.NOBUBANK.WWW...", "payment_url": "https://myiskapay.com/payment/INV-1-20260412143000-AB1C", "callback_url": "https://yoursite.com/callback", "return_url": "https://yoursite.com/return", "expired_at": "2026-04-12T15:30:00.000000Z", "created_at": "2026-04-12T14:30:00.000000Z" } } ``` ``` -------------------------------- ### Create New QRIS Payment Source: https://myiskapay.com/api/docs.json Initiates a new QRIS payment transaction. This endpoint is used to generate payment details for a customer to complete a transaction. ```APIDOC ## POST /api/gateway/payments ### Description Buat pembayaran QRIS baru ### Method POST ### Endpoint /api/gateway/payments ### Parameters #### Request Body - **amount** (number) - Required - Minimum: 2000, Maximum: 50000000 - **customer_name** (string) - Required - Maximum: 100 - **merchant_order_id** (string) - Optional - Maximum: 100 - Auto-generated jika kosong - **payment_method** (string) - Optional - Enum: [qris, bank_transfer, e_wallet] - **customer_email** (string) - Optional - Maximum: 100 - **customer_phone** (string) - Optional - Maximum: 20 - **description** (string) - Optional - Maximum: 255 - **callback_url** (string) - Optional - Format: url, Maximum: 500 - **return_url** (string) - Optional - Format: url, Maximum: 500 - **expired_time** (integer) - Optional - Minimum: 300, Maximum: 86400, Default: 3600 ### Response #### Success Response (201) - **payment_id** (string) - Description - **merchant_order_id** (string) - Description - **amount** (number) - Description - **total_amount** (number) - Description - **unique_amount** (number) - Description - **status** (string) - Description - **payment_method** (string) - Description - **qr_code** (string) - Description - **qr_string** (string) - Description - **payment_url** (string) - Description - **callback_url** (string) - Description - **return_url** (string) - Description - **expired_at** (string) - Description - **created_at** (string) - Description ``` -------------------------------- ### Verify Callback Signature (PHP) Source: https://myiskapay.com/api/docs Verifies the signature of an incoming callback to ensure data integrity. It concatenates specific payload fields and hashes them using SHA-256, comparing the result with the provided signature. ```php $expected = hash('sha256', $payload['payment']['merchant_order_id'] . $payload['payment']['status'] . $payload['payment']['amount'] . $payload['payment']['id'] ); if ($expected === $payload['signature']) { // Callback valid } ``` -------------------------------- ### Callback Payload Fields Source: https://myiskapay.com/api/docs This section details the fields available in the callback payload, their types, and descriptions. It's crucial for processing payment completion events. ```APIDOC ## Callback Payload Fields ### Payload Fields | Field | Type | Description | |---|---|---| | event | string | Always `"payment.completed"` | | payment.id | integer | Payment ID | | payment.merchant_order_id | string | Your Order ID | | payment.amount | integer | Original nominal amount (e.g., `50000`) | | payment.total_amount | integer | Nominal + unique amount | | payment.unique_amount | integer | Unique amount | | payment.status | string | Actual status: `paid`, `expired`, or `failed` | | payment.payment_method | string | Payment method (default: `qris`) | | payment.created_at | string | Payment creation time (ISO 8601) | | payment.paid_at | string|null| Time payment was successfully paid, `null` if not yet paid or failed | | payment.expired_at | string | Expiration time (ISO 8601) | | customer.name | string|null| Customer name from payment creation | | customer.email | string|null| Customer email from payment creation | | customer.phone | string|null| Customer phone from payment creation | | description | string|null| Description from payment creation | | timestamp | string | Time callback was sent (ISO 8601) | | signature | string | SHA-256 hash for verification | **Important:** The `event` field is always `"payment.completed"`. Use `payment.status` to determine the actual status. Amounts are integers; ensure signature calculation uses these integer values directly. ``` -------------------------------- ### Callback Payload Structure Source: https://myiskapay.com/api/docs.json This section describes the structure of the callback payload received from Myiskapay, detailing the fields related to payment, customer, and signature. ```APIDOC ## Callback Payload Structure ### Description This describes the structure of the callback payload. ### Fields - **_amount** (integer) - Nominal unik (bilangan bulat) - **status** (string) - Enum: ["paid", "expired", "failed"] - Status aktual pembayaran - **payment_method** (string) - Default: "qris" - **created_at** (string) - Format: ISO 8601 - **paid_at** (string|null) - Format: ISO 8601 - null jika belum/gagal bayar - **expired_at** (string) - Format: ISO 8601 - **customer** (object) - **name** (string|null) - Dari create payment - **email** (string|null) - Dari create payment - **phone** (string|null) - Dari create payment - **description** (string|null) - Dari create payment - **timestamp** (string) - Format: ISO 8601 - Waktu callback dikirim - **signature** (string) - SHA-256 untuk verifikasi ``` -------------------------------- ### Retry Mechanism Source: https://myiskapay.com/api/docs.json Information about the retry mechanism for callbacks, including maximum attempts and delays. ```APIDOC ## Retry Mechanism ### Description Information about the retry mechanism for callbacks, including maximum attempts and delays. ### Max Attempts 5 ### Backoff Seconds [5, 15, 30, 60, 120] ### Initial Delay Seconds 3 ### Note Callbacks are sent 3 seconds after the status update. Retries occur if the response is not 2xx. ``` -------------------------------- ### List Payments Source: https://myiskapay.com/api/docs.json Retrieves a list of payments with filtering and pagination capabilities. This endpoint helps in tracking transaction history. ```APIDOC ## GET /api/gateway/payments ### Description Daftar pembayaran dengan filter dan pagination ### Method GET ### Endpoint /api/gateway/payments ### Parameters #### Query Parameters - **status** (string) - Optional - Enum: [pending, completed, failed, cancelled, expired] - **payment_method** (string) - Optional - Enum: [qris, bank_transfer, e_wallet] - **date_from** (date) - Optional - Format: YYYY-MM-DD - **date_to** (date) - Optional - Format: YYYY-MM-DD - **limit** (integer) - Optional - Minimum: 1, Maximum: 100, Default: 20 - **page** (integer) - Optional - Minimum: 1 ### Response #### Success Response (200) - (List of payment objects, structure similar to Check Payment Status response) ``` -------------------------------- ### Check Payment Status by Merchant Order ID Source: https://myiskapay.com/api/docs This cURL command allows you to check the status of a payment using its unique merchant order ID. Replace 'your_api_key' and the order ID with your specific values. This is useful for verifying payment success or failure. ```bash curl https://myiskapay.com/api/gateway/payments/INV-1-20260412143000-AB1C \ -H "X-API-Key: your_api_key" ``` -------------------------------- ### Error Codes Source: https://myiskapay.com/api/docs A reference of common error codes returned by the Iskpay API, along with their status and descriptions. ```APIDOC ## Error Codes | Code | Status | Description | |---|---|---| | 200 | OK | Request successful | | 201 | Created | Payment successfully created | | 401 | Unauthorized | Invalid or missing API key | | 403 | Forbidden | Rate limit exceeded or account inactive | | 404 | Not Found | Payment not found | | 422 | Validation Error | Invalid parameters | | 429 | Too Many Requests | Rate limit exceeded or too many pending payments | | 500 | Server Error | Internal server error | ``` -------------------------------- ### Error Codes Source: https://myiskapay.com/api/docs.json A list of possible error codes returned by the API and their meanings. ```APIDOC ## Error Codes ### Description A list of possible error codes returned by the API and their meanings. ### Codes - **401**: API key tidak valid - **403**: Rate limit / akun tidak aktif - **404**: Resource tidak ditemukan - **422**: Validation error - **429**: Too many requests - **500**: Internal server error ``` -------------------------------- ### Check Payment Status Source: https://myiskapay.com/api/docs.json Retrieves the status of a payment using either the payment ID or the merchant order ID. The system automatically handles expiration if the payment time has passed. ```APIDOC ## GET /api/gateway/payments/{id} ### Description Cek status pembayaran (by payment_id atau merchant_order_id). Auto-expire jika sudah lewat waktu. ### Method GET ### Endpoint /api/gateway/payments/{id} ### Parameters #### Path Parameters - **id** (string) - Required - Payment ID or Merchant Order ID ### Response #### Success Response (200) - **payment_id** (string) - Description - **merchant_order_id** (string) - Description - **amount** (number) - Description - **total_amount** (number) - Description - **unique_amount** (number) - Description - **status** (string) - Description - **payment_method** (string) - Description - **qr_code** (string) - Description - **qr_string** (string) - Description - **paid_at** (string) - Description - **expired_at** (string) - Description - **created_at** (string) - Description - **updated_at** (string) - Description - **time_remaining** (object) - Description - Only available when status is pending, otherwise null. - **total_seconds** (integer) - Total remaining time in seconds. - **hours** (integer) - Remaining hours. - **minutes** (integer) - Remaining minutes. - **seconds** (integer) - Remaining seconds. - **is_expired** (boolean) - Whether the payment has expired. - **formatted** (string) - Formatted time remaining in HH:MM:SS format. - **provider_reference** (string) - Description - **return_url** (string) - Description ### Notes If `expired_at` has passed and the status is still pending, the API will automatically update the status to 'expired'. ``` -------------------------------- ### Cancel Pending Payment Source: https://myiskapay.com/api/docs.json Allows merchants to cancel a pending payment transaction. This is useful for managing outstanding transactions that are no longer required. ```APIDOC ## POST /api/gateway/payments/{id}/cancel ### Description Batalkan pembayaran pending ### Method POST ### Endpoint /api/gateway/payments/{id}/cancel ### Parameters #### Path Parameters - **id** (string) - Required - Payment ID ### Response #### Success Response (200) - **payment_id** (string) - Description - **status** (string) - Description - **cancelled_at** (string) - Description ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.