Payment Notification API

In the SNAP-based Core API flow, Midtrans will call Payment Notification API on the merchant side to send payment notifications. Merchant should implement this Payment Notification API as stated in the contract below.

📘

Midtrans will generate a pair of private and public key for signature generation and share the public key to merchant. Merchant will then need to give Midtrans a partner id that will be used in request header as X-PARTNER-ID.

🚧

Please make sure to whitelist this set of IPs to be able to accept notification from Midtrans.

EnvironmentIPs
Staging3.1.141.98/32
52.76.190.190/32
13.251.192.204/32
Production13.228.166.126/32
52.220.80.5/32
3.1.123.95/32

Receiving payment notifications for GoPay and GoPay Tokenization (non Pre-Auth) transaction

This section will describe how merchant should implement payment notification API for GoPay and GoPay Tokenization (non-Pre Auth) transactions for Midtrans to call.

Path/{version}/debit/notify
HTTP MethodPOST
Versionv1.0
SNAP Service Code56

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 asymmetric signature

Asymmetric-Signature format:

SHA256withRSA (privateKey, stringToSign) with

stringToSign = HTTPMethod +”:“+ EndpointUrl +":“+ Lowercase(HexEncode(SHA-256(minify(RequestBody)))) + ":“ + TimeStamp

X-PARTNER-ID String M Unique identifier for partner
X-EXTERNAL-ID String M Numeric string. 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
X-PARTNER-ID: 
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345

Request Body

Field Name Field Type Mandatory Field Description
createdTime String O Transaction created timestamp
latestTransactionStatus String M Latest transaction status

Possible Values:

  • 00 - Success
  • 03 - Pending
  • 04 - Refunded
  • 05 - Canceled
  • 06 - Failure

    08 - Expiry

    09 - Rejected

originalReferenceNo String M Transaction identifier on service provider system. For e.g: GopayOrderId
finishedTime String O Transaction completed timestamp (for latestTranscationStatus = 00)
originalPartnerReferenceNo String O Original transaction identifier on service consumer system. (Merchant’s orderId)
originalExternalId String(36) O Original External-ID on header message when doing charge (/payment-host-to-host)
merchantId String O Merchant ID
amount Object O Transaction amount
amount.value String M Transaction amount
amount.currency String M Transaction currency
additionalInfo Object M Additional info
additionalInfo.refundHistory Array of Object C Array of refund transactions. Only available if transaction status is refund
additionalInfo.refundHistory.refundNo String M Unique identifier of refund transaction generated by provider.
additionalInfo.refundHistory.partnerRefundNo String M Unique identifier of refund transaction generated by client.
additionalInfo.refundHistory.refundAmount Object M Refund amount
additionalInfo.refundHistory.refundAmount.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.refundHistory.refundAmount.currency String M Currency
additionalInfo.refundHistory.reason String M Refund reason
additionalInfo.refundHistory.refundTime String M Refund time
additionalInfo.totalRefundAmount Object C Total refund amount. Only available if transaction status is refund or partial refund.
additionalInfo.totalRefundAmount.value String M Total refund amount. If it's IDR then the value includes 2 decimal digits.

e.g. IDR 10.000,- will be placed with 10000.00

additionalInfo.totalRefundAmount.currency String M Currency
additionalInfo.fraudStatus String M Detection result by Fraud Detection System (FDS)
additionalInfo.validUpTo String M The time when the payment will be automatically expired. Using ISO 8601 format.
additionalInfo.payOptionDetails Array of Object M Payment option detail
additionalInfo.payOptionDetails.payMethod String M Gopay
additionalInfo.payOptionDetails.payOptions String M Gopay payment option used
{
    "createdTime": "2020-01-01T00:00:00+07:00",
    "latestTransactionStatus": "00",
    "originalReferenceNo": "gopayOrderId",
    "finishedTime": "2020-01-02T00:00:00+07:00",
    "originalPartnerReferenceNo": "merchant-order-id",
    "transactionStatusDesc": "desc",
   "originalExternalId":"merchant-order-id",
    "additionalInfo": {
        “payOptionDetails” : [{
          "payMethod":"GOPAY",
            "payOption": "GOPAY_WALLET"
        }], 
        "fraudStatus": "accept",
         "refundHistory":[
  	{
     	     	"refundNo":"96194816941239812",
     	     	"partnerReferenceNo":"239850918204981205970",
          		"refundAmount":{
          	   	     	"value":"12345678.00",
         	    	     	"currency":"IDR"
     	     	},
     	     	"refundStatus":"00",
     	     	"refundDate":"2020-12-23T07:44:16+07:00",
          		"reason":"Customer Complain"
  	}
   ],
        "validUpTo": "2021-01-01T00:00:00+07:00",
    }
}

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.
{
   "responseCode":"2005600",
   "responseMessage":"Request has been processed successfully"
}


Receiving payment notifications for GoPay QRIS transaction

This section will describe how merchant should implement payment notification API for GoPay QRIS transactions for Midtrans to call.

Path/{version}/qr/qr-mpm-notify
HTTP MethodPOST
Versionv1.0
SNAP service code52

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 asymmetric signature

Asymmetric-Signature format :

SHA256withRSA (privateKey, stringToSign) with

stringToSign = HTTPMethod +”:“+ EndpointUrl +":“+ Lowercase(HexEncode(SHA-256(minify(RequestBody)))) + ":“ + TimeStamp

X-PARTNER-ID String M Unique identifier for caller
X-EXTERNAL-ID String M Numeric string. 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:2020-01-01T00:00:00+07:00
X-SIGNATURE: da1fa417c72d6b91c257e01e54fac824
X-PARTNER-ID: 
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345

Request Body

Field Name Field Type Mandatory Field Description
originalReferenceNo String M Transaction identifier on service provider system. For e.g: GopayOrderId
originalPartnerReferenceNo String O Original transaction identifier on service consumer system. (Merchant’s orderId)
latestTransactionStatus String M Latest transaction status

Possible Values:

  • 00 - Success
  • 03 - Pending
  • 04 - Refunded
  • 05 - Canceled
  • 06 - Failure

    08 - Expiry

    09 - Rejected

amount Object O Amount of the order
amount.value String M Transaction amount
amount.currency String M Transaction currency
additionalInfo Object M Additional info
additionalInfo.refundHistory Array of Object C Array of refund transactions. Only available if transaction status is refund
additionalInfo.refundHistory.refundNo String M Unique identifier of refund transaction generated by provider.
additionalInfo.refundHistory.partnerRefundNo String M Unique identifier of refund transaction generated by client.
additionalInfo.refundHistory.refundAmount Object M Refund amount
additionalInfo.refundHistory.refundAmount.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.refundHistory.refundAmount.currency String M Currency
additionalInfo.refundHistory.reason String M Refund reason
additionalInfo.refundHistory.refundTime String M Refund time
additionalInfo.totalRefundAmount Object C Total refund amount. Only available if transaction status is refund or partial refund.
additionalInfo.totalRefundAmount.value String M Total refund amount. If it's IDR then the value includes 2 decimal digits.

e.g. IDR 10.000,- will be placed with 10000.00

additionalInfo.totalRefundAmount.currency String M Currency
{
   "originalReferenceNo":"2020102977770000000009",
   "originalPartnerReferenceNo":"2020102900000000000001",
   "latestTransactionStatus":"00",
   "transactionStatusDesc":"success",
   "amount":{
      "value":"12345678.00",
      "currency":"IDR"
   },
   "externalStoreID":"124928924949487",
   "additionalInfo":{

   }
}

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.
{
   "responseCode":"2005600",
   "responseMessage":"Request has been processed successfully"
}

List of response code

Response Code HTTP Status Description
2005200 200 Successful
2025200 202 Transaction still on process
4005200 400 General request failed error, including message parsing failed.
4005201 400 Invalid format
4005202 400 Missing or invalid format on mandatory field
4015200 401 General unauthorized error (No Interface Def, API is Invalid, Oauth Failed, Verify Client Secret Fail, Client Forbidden Access API, Unknown Client, Key not Found)
4015201 401 Token found in request is invalid (Access Token Not Exist, Access Token Expiry)
4015203 401 Token not found in the system. This occurs on any API that requires token as input parameter
4035200 403 Transaction expired
4035201 403 This merchant is not allowed to call Direct Debit APIs
4035202 403 Exceeds Transaction Amount Limit
4035203 403 Suspected Fraud
4035204 403 Too many request, Exceeds Transaction Frequency Limit
4035205 403 Account or User status is abnormal
4035206 403 Cut off In Progress
4035209 403 The account is dormant
4035214 403 Insufficient Funds
4035215 403 Transaction Not Permitted
4035216 403 Suspend Transaction
4035218 403 Indicates inactive account
4035219 403 Merchant is suspended from calling any APIs
4035220 403 Merchant aggregated purchase amount on that day exceeds the agreed limit
4035221 403 Set limit not allowed on particular token
4035222 403 The token limit desired by the merchant is not within the agreed range between the merchant and the Issuer
4035223 403 Account aggregated purchase amount on that day exceeds the agreed limit
4045200 404 Invalid transaction status
4045201 404 Transaction not found
4045202 404 Invalid Routing
4045204 404 Transaction is cancelled by customer
4045208 404 Merchant does not exist or status abnormal
4045210 404 Invalid API transition within a journey
4045213 404 The amount doesn't match with what supposed to
4045216 404 Partner number can't be found
4045217 404 Terminal does not exist in the system
4045218 404 Inconsistent request parameter
4055200 405 Requested function is not supported
4055201 405 Requested operation to cancel/refund transaction Is not allowed at this time.
4095200 409 Cannot use same X-EXTERNAL-ID in same day
4095201 409 Transaction has previously been processed indicates the same partnerReferenceNo already success
4295200 429 Maximum transaction limit exceeded
5005200 500 General Error
5005201 500 Unknown Internal Server Failure, Please retry the process again
5005202 500 Backend system failure, etc
5045200 504 timeout from the issuer

Receiving payment notifications for Bank Transfer (VA)

This section will describe how merchant should implement payment notification API for Bank Transfer (VA) transactions for Midtrans to call.

Path/{version}/transfer-va/payment
HTTP MethodPOST
Versionv1.0
SNAP service code25

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 asymmetric signature

Asymmetric-Signature format :

SHA256withRSA (privateKey, stringToSign) with

stringToSign = HTTPMethod +”:“+ EndpointUrl +":“+ Lowercase(HexEncode(SHA-256(minify(RequestBody)))) + ":“ + TimeStamp

X-PARTNER-ID String M Unique identifier for caller
X-EXTERNAL-ID String M Numeric string. 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:2020-01-01T00:00:00+07:00
X-SIGNATURE:da1fa417c72d6b91c257e01e54fac824
X-PARTNER-ID:G12345678
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345

Request Body

Field Name Field Type Mandatory Field Description
partnerServiceId String(8) M partnerServiceId from the virtual account number
customerNo String(20) M customerNo from the virtual account number
virtualAccountNo String(28) M Virtual account number for the transaction
virtualAccountName String(255) O The customer name
virtualAccountEmail String(255) O The customer’s email
virtualAccountPhone String(30) O The customer’s phone number
trxId String(64) M This value will be the trxId used in the create VA request.
paymentRequestId String C Unique identifier for this Payment from Midtrans.

This value will exist if the payment has been completed

paidAmount Object C Amount paid for this transaction

This value will exist if the payment has been completed

paidAmount.value String(16, 2) M The numeric string of the amount up to two decimal places
paidAmount.currency String(3) M The currency of the value paid. Should be IDR
trxDateTime Date(25) M ISO-8601 datetime in GMT+7 when the VA is paid
referenceNo String O Payment auth code generated by Midtrans
additionalInfo Object O
additionalInfo.bank String M Indicates the bank chosen to create the VA at. The banks that can be used will differ based on the banks chosen by the merchant during the onboarding process. Possible values are
  • Permata
  • BCA
  • Mandiri
  • CIMB
  • BNI
  • BRI
additionalInfo.merchantId String(10) M This is the merchantId shared by Midtrans during the onboarding process
additionalInfo.paymentFlagStatus String(2) M Status for Payment Flag

00 - Success

01 - Initiated

02 - Paying

03 - Pending

04 - Refunded

05 - Canceled

06 - Failed

07 - Not found

08 - Expired

09 - Denied

additionalInfo.customField Object M A collection of up to three fields sent by the merchant. It will also be displayed on the Dashboard under “order detail”
additionalInfo.customField.1 String(255) M First field that contains the custom data set by the merchant
additionalInfo.customField.2 String(255) M Second field that contains the custom data set by the merchant
additionalInfo.customField.3 String(255) M Third field that contains the custom data set by the merchant
{
    "partnerServiceId":"  088899",
    "customerNo":"12345678901234567890",
    "virtualAccountNo":"  08889912345678901234567890",
    "virtualAccountName":"Jokul Doe",
    "virtualAccountEmail":"[email protected]",
    "virtualAccountPhone":"6281828384858",
    "trxId":"abcdefgh1234",
    "paymentRequestId":"abcdef-123456-abcdef",
    "paidAmount":{
       "value":"12345678.00",
       "currency":"IDR"
    },
    "trxDateTime":"20201231T235959Z",
    "referenceNo":"123456789012345",
    "additionalInfo":{
       "bank":"BCA",
       "paymentFlagStatus": "00",
       "merchantId":"G059876677",
       "customField": {
          "1": "custom-field-1",
          "2": "custom-field-2",
          "3": "custom-field-3"
       }
    }
 }

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:2020-01-01T00:00:00+07:00

Response Body

Field Name Field Type Mandatory Field Description
responseCode String(7) M Response code
responseMessage String(150) M Response description
virtualAccountData Object M
virtualAccountData.partnerServiceId String(8) M partnerServiceId from Create VA Response
virtualAccountData.customerNo String(29) M customerNo from Create VA Response
virtualAccountData.virtualAccountNo String(28) M Virtual account number for the transaction
virtualAccountData.trxId String(64) M This value will be the trxId used in the create VA request.
virtualAccountData.trxDateTime Date(25) M ISO-8601 datetime in GMT+7 when the VA is paid
{
    "responseMessage": "Successful",
    "responseCode": "2002500",
    "virtualAccountData": {
        "partnerServiceId": "  088899",
        "customerNo": "12345678901234567890",
        "virtualAccountNo": "  08889912345678901234567890",
        "trxDateTime":"20201231T235959Z",
        "trxId": "midtrans-testing-001"
}

List of response code

Response Code HTTP Status Description
2003100 200 Success
4003102 400 Invalid Mandatory Field
4013100 401 Unauthorized.
5003101 500 Internal Server Error
5043100 504 Timeout
2002700 200 Success
4012700 401 Unauthorized. Signature
5002700 500 Internal Server Error
4002700 400 Bad Request
4042713 404 Invalid Amount
4002701 400 Invalid Field Format X-TIMESTAMP
2002700 200 Success
4012700 401 Unauthorized. Signature
5002700 500 Internal Server Error
4002700 400 Bad Request
4042713 404 Invalid Amount
4002701 400 Invalid Field Format X-TIMESTAMP

Notification retry mechanism for Open API

In case we got error response when sending notification (non 2xx response) to merchants, Midtrans will retry up to 3 times with exponential interval. For now our retry mechanism is as follows:

1st retry delay time = 20ms
2nd retry delay time = 40ms
3rd retry delay time = 80ms

Notes: this interval can change anytime as part of improvement, we will update it periodicaly