This section will explain how merchant can initiate GoPay Tokenization (Pre-Auth) transactions using SNAP-based CoreAPI specification.
- In order to do GoPay Tokenization transaction, merchant should link the customer's GoPay account first by initiating the Account Linking API.
- Once linked, merchant can reserve user's balance by initiating auth payment (auth API)
- To actually deduct user's balance merchant will need to capture the authorized transaction (capture API)
- If merchant wants to release user's balance without actually deduct the balance, merchant will need to void the transaction by calling Void API. Authorized transaction that is not captured after its expiry time will be auto canceled.
- Merchant can also do other subsequent actions such as Refund, and Get Status.
Currently GoPay Tokenization pre-auth only supports No PIN transaction. Please contact your Midtrans sales representative to enable pre-auth transaction.
GoPay Tokenization in BI-SNAP flow can also support both GoPay & GoPay Later payment. Merchant should pass the corresponding payment option token as payOptionDetails.additionalInfo.paymentoptiontoken in the request body. The payment option token can be retrieved from Binding Inquiry API.
Creating GoPay Tokenization Pre-Auth transaction
![](https://files.readme.io/afd0c92-SNAP_based_account_linking_flow-tokenization_preauth.drawio.png)
Reserving user's balance - Auth Payment API
This section describes how merchants can reserve user's balance without actually deducting it from the start by calling Auth Payment API.
Path | /{version}/auth/payment |
---|---|
HTTP Method | POST |
Version | v1.0 |
SNAP service code | 63 |
Request Header
Field Name | Field Type | Mandatory | Field Description | |
Content-type | String | M | Media type of the resource, i.e. application/json | |
X-TIMESTAMP | String | M | Client’s current local time in ISO-8601 format | |
X-SIGNATURE | String | M | Created using symmetric signature HMAC_SHA512 algorithm | |
Authorization | String | M | Represents access_token of a request; string starts with keyword “Bearer ” followed by access_token. Can get this token from Access Token B2B API response. | |
Authorization-Customer | String | M | accessToken which Gopay will be sharing once linking is complete. string starts with keyword “Bearer ”followed by access_token. | |
X-PARTNER-ID | String | M | Unique identifier for caller | |
X-EXTERNAL-ID | String | M | Numeric string. Preferably UUID. Reference number that should be unique in the same day or 1 day idempotency key | |
CHANNEL-ID | String | M | Mandatory field from Bank Indonesia that can take any value with correct format 5 digits numeric string | |
X-DEVICE-ID | String | M | Device identification on which the API services are currently being accessed by the end user (customer). Sample: Mobile Application: |
Content-type:application/json
X-TIMESTAMP:2024-03-19T14:30:00+07:00
X-SIGNATURE: da1fa417c72d6b91c257e01e54fac824
Authorization: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
Authorization-Customer: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
X-PARTNER-ID: BMRI
X-DEVICE-ID: 0987ADCASA
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345
Request Body
Field Name | Field Type | Mandatory | Field Description | |
partnerReferenceNo | String (64) | M | Merchant order-id
Only used for debugging purposes on the server side. |
|
merchantId | String(64) | M | Merchant’s unique ID provided by Midtrans. | |
amount | Object | O | Transaction amount | |
amount.value | String (ISO4217) | M | Net amount of the transaction. If it's IDR then value includes 2 decimal digits. e.g. IDR 10.000,- will be placed with 10000.00 | |
amount.currency | String(3) | M | Currency | |
title | String(256) | M | Order title | |
items | Array of Object | O | Item details | |
items.id | String(32) | O | Item ID | |
items.price | Object | M | Price of the item | |
items.price.value | String (ISO4217) | M | Item price value | |
items.price.currency | String | M | Item price currency | |
items.quantity | String(16) | M | Item quantity | |
items.name | String(64) | M | Item name | |
items.brand | String(64) | O | Brand name of the item | |
items.category | String(64) | O | Category of the item | |
items.merchantName | String(64) | O | Name of the merchant selling the item. | |
additionalInfo | Object | M | Additional Information | |
additionalInfo.payOptionDetails.payOption | String (64) | M | Payment option which shows the provider of this payment
Possible value: GOPAY_WALLET |
|
additionalInfo.payOptionDetails.payMethod | String (64) | M | Possible value: `GOPAY` | |
additionalInfo.payOptionDetails.transAmount | Object | M | Payment transaction amount | |
additionalInfo.payOptionDetails.transAmount.value | String (16,2) | M | Transaction amount that will be paid using this payment method If it's IDR then value includes 2 decimal digits.
e.g. IDR 10.000,- will be placed with 10000.00 |
|
additionalInfo.payOptionDetails.transAmount.currency | String (3) | M | IDR | |
additionalInfo.payOptionDetails.additionalInfo.paymentOptionToken | String | M | paymentOption token | |
additionalInfo.customerDetails | Object | O | Customer detail information | |
additionalInfo.customerDetails.phone | String(15) | O | Customer phone number | |
additionalInfo.customerDetails.email | String(255) | O | Customer email | |
additionalInfo.customerDetails.firstName | String(255) | O | Customer first name | |
additionalInfo.customerDetails.lastName | String(255) | O | Customer last name | |
additionalInfo.customerDetails.billingAddress | Object | O | Billing address information | |
additionalInfo.customerDetails.billingAddress.firstName | String(255) | O | Billing address first name | |
additionalInfo.customerDetails.billingAddress.lastName | String(255) | O | Billing address last name | |
additionalInfo.customerDetails.billingAddress.phone | String(15) | O | Billing address phone number | |
additionalInfo.customerDetails.billingAddress.address | String(255) | O | Billing address detail | |
additionalInfo.customerDetails.billingAddress.city | String(255) | O | Billing address city | |
additionalInfo.customerDetails.billingAddress.postalCode | String(255) | O | Billing address postal code | |
additionalInfo.customerDetails.billingAddress.countryCode | String(15) | O | Billing address country code | |
additionalInfo.customerDetails.shippingAddress | Object | O | Shipping address information | |
additionalInfo.customerDetails.shippingAddress.firstName | String(255) | O | Shipping address first name | |
additionalInfo.customerDetails.shippingAddress.lastName | String(255) | O | Shipping address last name | |
additionalInfo.customerDetails.shippingAddress.phone | String(15) | O | Shipping address phone number | |
additionalInfo.customerDetails.shippingAddress.address | String(255) | O | Shipping address detail | |
additionalInfo.customerDetails.shippingAddress.city | String(255) | O | Shipping address city | |
additionalInfo.customerDetails.shippingAddress.postalCode | String(255) | O | Shipping address postal code | |
additionalInfo.customerDetails.shippingAddress.countryCode | String(15) | O | Shipping address country code | |
additionalInfo.validUpTo | String(25) | O | The time when the payment will be automatically expired. Using ISO 8601 format
(Maximum value: 180 days from trx time, Minimum value: 20 second, default value: 7 days) |
{
"partnerReferenceNo": "merchant-order-id",
"merchantId": “aMerchantId",
"amount": {
"value": "12345678.00",
"currency": "IDR"
},
"items": [
{
"id": "8za1ieleavwusxn6u5re60ri",
"price": {
"value": "12345678.00",
"currency": "IDR"
},
"quantity": “1”,
"name": "subscription ",
"brand": "brand ",
"category": "Subsciption ",
"url": "www.google.com ",
"merchantName": "amazon prime"
}
],
"additionalInfo": {
"payOptionDetails": [
{
"payMethod": "GOPAY",
"payOption": "GOPAY_WALLET",
"transAmount": {
"value": "12345678.00",
"currency": "IDR"
},
"additionalInfo": {
"paymentOptionToken": "aGoPayWalletToken / aPayLaterToken"
}
}
],
"customerDetail": {
"phone": "81234532422",
"firstName": "farz",
"lastName": "zsasa",
"email": "[email protected]",
"billingAddress": {
"firstName": "billingFirstName",
"lastName": "billingLastName",
"phone": "billingPhone",
"address": "billingAddress",
"city": "billingCity",
"postalCode": "12790",
"countryCode": "CZH"
},
"shippingAddress": {
"firstName": "shippingFirstName",
"lastName": "shippingLastName",
"phone": "shippingPhone",
"address": "shippingAddress",
"city": "shippingCity",
"postalCode": "12790",
"countryCode": "CZH"
},
}
}
}
Response Header
Field Name | Field Type | Mandatory | Field Description | |
Content-type | String | M | Media type of the resource, i.e. application/json | |
X-TIMESTAMP | String | M | Client’s current local time in ISO-8601 format |
Content-type: application/json
X-TIMESTAMP: 2024-03-19T14:30:00+07:00
Response Body
Field Name | Field Type | Mandatory | Field Description | |
responseCode | String (7) | M | Error code to specify the error returned. | |
responseMessage | String (150) | M | Debug message to provide more information. | |
referenceNo | String (256) | O | Unique transaction identifier from payment provider system e.g : Gopay order ID. | |
partnerReferenceNo | String (32) | O | Unique transaction identifier from Merchant (Merchant order ID). | |
additionalInfo | Object | O | Additional information | |
additionalInfo.amount | Object | O | Transaction Total Amount Object | |
additionalInfo.amount.value | String | M | Net amount of the refund. If it's IDR then the value includes 2 decimal digits.
e.g. IDR 10.000,- will be placed with 10000.00 |
|
additionalInfo.amount.currency | String | M | Currency | |
additionalInfo.transactionTime | String | O | Timestamp of transaction in ISO 8601 format. Time zone: GMT+7. | |
additionalInfo.transactionStatus | String | O | Status of GoPay transaction.
Possible Values:
|
|
additionalInfo.fraudStatus | String | O | Fraud status | |
additionalInfo.payOptionDetails | Array of Object | M | Payment option detail | |
additionalInfo.payOptionDetails.payMethod | String | M | Gopay | |
additionalInfo.payOptionDetails.payOptions | String | M | Gopay payment option used | |
additionalInfo.validUpTo | String(25) | O | The time when the payment will be automatically expired. Using ISO 8601 format |
{
"responseCode":"20054000",
"responseMessage":"Request has been processed successfully",
"referenceNo":"Gopay-order-id",
"partnerReferenceNo":"merchant-order-id",
"additionalInfo":{
"grossAmount":"10000.00",
"currency":"IDR"
"paymentType":"Gopay",
"transactionTime":"2024-05-22T07:48:08.56Z",
"transactionStatus":"settlement"
"fraudStatus":"some-fraud-status" ,
“payOptionDetails” : [{
"payMethod":"GOPAY",
"payOption": "GOPAY_WALLET"
}],
"validUpTo":"2024-05-22T16:00:00.00Z"
}
}
{
"responseCode":"4006301",
"responseMessage":"There is some issue with the transaction request"
}
List of Response code
Response Code | HTTP Status Code | Response Message |
2006300 | 200 | Success |
4006302 | 400 | Invalid Mandatory Field {Field Name} |
4016300 | 401 | Unauthorized. Auth token required |
4016301 | 401 | Invalid Token (B2B) |
4016302 | 401 | Invalid Customer Token |
4031003 | 403 | Suspected Fraud |
4031014 | 403 | Insufficient Funds |
5006301 | 500 | Internal Server Error |
5046300 | 504 | Timeout |
Capturing user's balance - Capture API
This section describes how merchants can capture a transaction that has been reserved/authorized and deduct user balance by calling Capture API.
Path | /{version}/auth/capture |
---|---|
HTTP Method | POST |
Version | v1.0 |
SNAP service code | 65 |
Request Header
Field Name | Field Type | Mandatory | Field Description | |
Content-type | String | M | Media type of the resource, i.e. application/json | |
X-TIMESTAMP | String | M | Client’s current local time in ISO-8601 format | |
X-SIGNATURE | String | M | Created using symmetric signature HMAC_SHA512 algorithm | |
Authorization | String | M | Represents access_token of a request; string starts with keyword “Bearer ” followed by access_token. Can get this token fromAccess Token B2B API response. | |
X-PARTNER-ID | String | M | Unique identifier for caller (client_id) | |
X-EXTERNAL-ID | String | M | Numeric string. Preferably UUID. Reference number that should be unique in the same day or 1 day idempotency key | |
CHANNEL-ID | String | M | Mandatory field from Bank Indonesia that can take any value with correct format 5 digits numeric string |
Content-type:application/json
X-TIMESTAMP:2024-03-19T14:30:00+07:00
X-SIGNATURE: da1fa417c72d6b91c257e01e54fac824
Authorization: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
X-PARTNER-ID: BMRI
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345
Request Body
originalReferenceNo | String(64) | C | Transaction identifier on service provider system. For e.g: GopayOrderId Note: either additionalInfo.originalExternalId or OriginalReferenceNo need to be filled If both fields have value, will use originalReferenceNo as the main identifier. |
|
originalPartnerReferenceNo | String (64) | M | Merchant order id | |
merchantId | String(64) | M | Merchant’s unique ID provided by Midtrans. | |
partnerCaptureNo | String (64) | M | Capture identifier generated by the partner | |
captureAmount | String | O | Transaction amount that merchant wants to capture. Currently only full capture is supported. |
|
captureAmount.value | String | M | Capture amount value | |
captureAmount.currency | String | M | Capture amount currency | |
title | String(256) | M | Order title | |
additionalInfo | ||||
additionalInfo.originalExternalId | String (36) | C | If merchant got a timeout from the auth endpoint, merchant can use this field using the X-EXTERNAL-ID value in the direct debit request header.
Note: either originalExternalId or OriginalReferenceNo need to be filled |
{
"originalReferenceNo": "2020102900000000000001",
"originalPartnerReferenceNo": "123123123123",
"partnerCaptureNo": "asdv-asdasdv-addasd-1231ewqqw-aaaa",
"merchantId": "merch00001",
"captureAmount": {
"value": "12345678.00",
"currency": "IDR"
},
"title": "aTitle",
"additionalData": {
"originalExternalId": "aId"
}
}
Response Header
Field Name | Field Type | Mandatory | Field Description | |
Content-type | String | M | Media type of the resource, i.e. application/json | |
X-TIMESTAMP | String | M | Client’s current local time in ISO-8601 format |
Content-type: application/json
X-TIMESTAMP: 2024-03-19T14:30:00+07:00
Response Body
Field Name | Field Type | Mandatory | Field Description | |
responseCode | String (7) | M | Error code to specify the error returned. | |
responseMessage | String (150) | M | Debug message to provide more information. | |
originalReferenceNo | String (256) | O | Transaction identifier on service provider system. For e.g: GopayOrderId | |
originalPartnerReferenceNo | String (32) | O | Transaction identifier on service consumer system | |
captureNo | String (64) | C | PJSP's capture identifier. Used to trace the capture when there's any issue occurred. | |
partnerCaptureNo | String (64) | O | Capture identifier generated by the partner | |
captureAmount | ||||
captureAmount.value | String (16,2) | O | Transaction amount that will be paid using this payment method If it's IDR then value includes 2 decimal digits.
e.g. IDR 10.000,- will be placed with 10000.00 |
|
captureAmount.currency | String | O | Currency For e.g: IDR |
{
"responseCode":"20054000",
"responseMessage":"Request has been processed successfully",
"originalReferenceNo":"2020102900000000000001",
"originalPartnerReferenceNo":"123123123123",
"captureNo":"asdv-asdasdv-addasd-1231ewqqw-aaaa",
"partnerCaptureNo":"asdv-asdasdv-addasd-1231ewqqw-aaaa",
"captureAmount":{
"value":"12345678.00",
"currency":"IDR"
}
}
{
"responseCode":"4006501",
"responseMessage":"There is some issue with the transaction request"
}
List of Response code
Response Code | HTTP Status Code | Response Message |
2006500 | 200 | Success |
4006502 | 400 | Invalid Mandatory Field {Field Name} |
4016500 | 401 | Unauthorized. Auth token required |
4016501 | 401 | Invalid Token (B2B) |
4036515 | 403 | Transaction Not Permitted.[reason]. |
5006501 | 500 | Internal Server Error |
5046500 | 504 | Timeout |