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

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