Create Payment
This endpoint is used to create new payment transactions. It supports various payment methods through a single uniform interface. You only need to change the method_type and method_detail parameters.
⚠️ Important: Only tenants with the Client role can access this endpoint. You must use an API Key, not a JWT.
POST /v1/payments/createRequest Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | ✅ | Must contain Bearer {api_key} |
Content-Type | string | ✅ | Always application/json |
X-Idempotency-Key | string | ✅ | A unique key per order (e.g., your system's order number) to prevent duplication in case of network errors |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | ✅ | The bill amount in the smallest unit (cents). Example: Rp 100,000 is written as 10000000 |
currency | string | ✅ | The currency. Currently only supports "IDR" |
method_type | string | ✅ | The payment method type. See the Method Type table |
method_detail | object | ✅ | Specific parameters for the payment method. Always include the "type" field with the same value as method_type. See per-method details below |
customer_name | string | ❌ | Your customer's name |
customer_email | string | ❌ | Customer's email (must be a valid email format if provided) |
customer_phone | string | ❌ | Customer's phone number (important for some E-Wallet types) |
items | array | ❌ | Details of products/services purchased by the customer |
expiry_minutes | integer | ❌ | Expiration time in minutes. Default: 60. Minimum: 2 (Winpay) |
Method Type (method_type)
| Value | Description |
|---|---|
virtual_account | Bank Virtual Account Transfer |
qris | QRIS Payment (Dynamic) |
e_wallet | Digital Wallets (OVO, DANA, etc.) |
over_the_counter | Payments at retail outlets (Alfamart, Indomaret) |
Method Detail
The method_detail field is required, and its object structure depends on the method_type value. Note that the "type" field must be present inside the method_detail object.
1. Virtual Account
{
"type": "virtual_account",
"bank": "BCA" // See active banks list at /v1/active-methods
}2. QRIS
{
"type": "qris"
}3. E-Wallet
{
"type": "e_wallet",
"wallet_type": "DANA" // OVO, DANA, SHOPEEPAY, etc.
}4. Over The Counter (Retail)
{
"type": "over_the_counter",
"store": "ALFAMART" // ALFAMART, INDOMARET
}Array Items
Optional array object for product details:
[
{
"id": "SKU-001",
"name": "Kopi Susu Gula Aren",
"price": 2500000,
"quantity": 2
}
](Remember: price is in cents, so 2500000 = Rp 25,000)
Response
The standard response structure returns payment details including method-specific instructions (method_data).
Success Response (200 OK)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "b6a3b2b8-f09d-4767-8fa0-68153c30a91f",
"payment_code": "TEST-12345678",
"idempotency_key": "order-123",
"amount": 10000000,
"currency": "IDR",
"method_type": "virtual_account",
"method_data": {
"type": "virtual_account",
"bank": "BCA",
"va_number": "88880123456789"
},
"status": "pending",
"provider": "winpay",
"provider_payment_id": "WP-998877",
"customer_name": "Budi Santoso",
"customer_email": "[email protected]",
"customer_phone": "081234567890",
"items": [],
"expires_at": "2026-07-21T12:00:00Z",
"paid_at": null,
"amount_paid": null,
"failure_reason": null,
"created_at": "2026-07-21T11:00:00Z",
"updated_at": "2026-07-21T11:00:00Z"
}
}Response Field method_data
This field changes according to the payment method, similar to the request's method_detail:
- Virtual Account:
{ "type": "virtual_account", "bank": "BCA", "va_number": "8888..." } - QRIS:
{ "type": "qris", "qr_string": "000201010211...", "qr_image_url": "https://..." } - E-Wallet:
{ "type": "e_wallet", "wallet_type": "DANA", "redirect_url": "https://...", "deeplink": "dana://..." } - Over The Counter:
{ "type": "over_the_counter", "store_name": "ALFAMART", "payment_code": "44445555" }
Complete Request Examples
1. Virtual Account
curl -X POST https://gerbang-pay-api.gai.co.id/v1/payments/create \
-H "Authorization: ApiKey gp_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: order-va-001" \
-d '{
"amount": 15000000,
"currency": "IDR",
"method_type": "virtual_account",
"method_detail": { "type": "virtual_account", "bank": "BCA" },
"customer_name": "Budi"
}'2. QRIS
curl -X POST https://gerbang-pay-api.gai.co.id/v1/payments/create \
-H "Authorization: ApiKey gp_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: order-qris-002" \
-d '{
"amount": 5000000,
"currency": "IDR",
"method_type": "qris",
"method_detail": { "type": "qris" }
}'3. E-Wallet
curl -X POST https://gerbang-pay-api.gai.co.id/v1/payments/create \
-H "Authorization: ApiKey gp_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: order-ewallet-003" \
-d '{
"amount": 2500000,
"currency": "IDR",
"method_type": "e_wallet",
"method_detail": { "type": "e_wallet", "wallet_type": "OVO" }
}'4. Over The Counter (Retail)
curl -X POST https://gerbang-pay-api.gai.co.id/v1/payments/create \
-H "Authorization: ApiKey gp_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: order-otc-004" \
-d '{
"amount": 10000000,
"currency": "IDR",
"method_type": "over_the_counter",
"method_detail": { "type": "over_the_counter", "store": "ALFAMART" }
}'Common Error Responses
400 Bad Request
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "bad request: Amount must be greater than zero"
}
}409 Idempotency Conflict
Occurs if you send the exact same X-Idempotency-Key but with different body parameters.
{
"success": false,
"error": {
"code": "IDEMPOTENCY_CONFLICT",
"message": "idempotency conflict: Same key submitted with different payload"
}
}502 Provider Error
Occurs if the Winpay or Midtrans server rejects your request (e.g., incorrect bank name).
{
"success": false,
"error": {
"code": "PROVIDER_ERROR",
"message": "provider error [winpay]: Bank BCA is not supported for this merchant"
}
}