Refund API

Initiating refund for GoPay and GoPay Tokenization (non Pre-Auth) transaction

This section will describe how a merchant can initiate refunds for GoPay and GoPay Tokenization (non-Pre Auth) transactions.

Path/{version}/debit/refund
HTTP MethodPOST
Versionv1.0
SNAP Service Code58

Request Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
X-SIGNATUREStringMCreated using symmetric signature HMAC_SHA512 algorithm
AuthorizationStringMRepresents access_token of a request; string starts with keyword “Bearer ” followed by access_token. Can get this token from Access Token B2B API response.
X-PARTNER-IDStringMUnique identifier for caller
X-EXTERNAL-IDStringMAlphanumeric string. We suggest merchant to use UUID format. The value should be unique.
In case of timeout, merchant can do:
  1. Use this value in get status API to get status transaction or
  2. Retry this request with the same X-EXTERNAL-ID and request body to avoid creating duplicate transaction
CHANNEL-IDStringMMandatory 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

Field NameField TypeMandatoryField Description
originalExternalIdString (36)CIf merchant got a timeout when calling charge API (POST /v1.0/debit/payment-host-to-host), merchant can pass the value of X-EXTERNAL-ID in the charge API request header as originalExternalId.

Note: Either originalExternalId or OriginalReferenceNo need to be passed in refund request.

partnerRefundNoString(64)MUnique identifier of refund transaction generated by merchant.

If not passed then Midtrans creates a new one. It is recommended to use this parameter to avoid double refund attempts. Allowed characters are alphabets, numbers, dash (-), and underscore (_).

originalPartnerReferenceNoString(64)MTransaction identifier on merchant side (merchant's order id).
originalReferenceNoString(64)CTransaction identifier on service provider system. For e.g: GopayOrderId

Note: Either originalExternalId or OriginalReferenceNo need to be passed. If both fields have value, will use originalReferenceNo as the main identifier.

refundAmountObjectOrefundAmount object, if amount not set, system will treat as full refund request.
refundAmount.valueString (16,2)ONet 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

refundAmount.currencyString (2)OCurrency.
reasonString (256)OReason for the refund. For Gopay transaction, this field will be shown on Gopay Order History
additionalInfoObjectOAdditional Information
additionalInfo.paymentProviderMetadataObjectOObject containing the payment provider’s metadata parameter. This is used whenever merchant needs to pass additional information to payment provider.In the case of GoPay Later Multi Month, merchant needs to pass the required risk data information as agreed with GoPay Later team.
{
    "originalExternalId": "merchant-x-external-id",
    "originalPartnerReferenceNo":"merchant-order-id",
    "partnerRefundNo" : "merchant-refund-no",
    "originalReferenceNo" : "gopay-order-id",
     "refundAmount" : {
      "value":"10000.00",
      "currency":"IDR"
   },
   "reason" : "some-reason"
   "additionalInfo": {
   		"paymentProviderMetadata": {
      	"subOrders*": [
					"subOrderId*": string,
					"quantity*": int,
					"amount*": long
				]
      }
 	 }
}

Response Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
Content-type: application/json
X-TIMESTAMP: 2024-03-19T14:30:00+07:00

Response Body

Field NameField TypeMandatoryField Description
responseCodeString (7)MResponse code
responseMessageString (150)MResponse description
originalReferenceNoString (256)MTransaction identifier on service provider system. For e.g: GopayOrderId
refundNoString(64)MGopay refund number
partnerRefundNoString(64)MUnique identifier of refund transaction generated by merchant.

Merchant refund ID. If not passed then Midtrans creates a new one. It is recommended to use this parameter to avoid double refund attempts. Allowed characters are alphabets, numbers, dash (-), and underscore (_).

refundAmountObjectOrefundAmount object
refundAmount.valueString (ISO 4217) (16,2)ONet 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

refundAmount.currencyString (2)OCurrency.
refundTimeString(25)MRefund time. ISO 8601
{
   "responseCode":"20058000",
   "responseMessage":"Request has been processed successfully",
   "originalReferenceNo": "2020102977770000000009",
   "refundNo":"2020102900000000000001",
   "partnerRefundNo":"2020102900000000002323232",
   "refundAmount" : {
      "value":"10000.00",
      "currency":"IDR"
   },
   "refundTime" : "2023-07-03T10:36:17+07:00"
}

List of Response code

Response CodeHTTP Status CodeResponse Message
2005800200Success
4005802400Invalid Mandatory Field
4015800401Unauthorized.
4015801401Invalid Token (B2B)
4035802403Exceeds Transaction Amount Limit
4035814403Insufficient Funds
4035815403Transaction Not Permitted.[reason].
4035823403Account Limit Exceed
4045801404Transaction Not Found
5005801500Internal Server Error
5045800504Timeout

Initiating refund for GoPay QRIS transaction

This section will describe how a merchant can initiate refunds for GoPay QRIS transactions.

Path/{version}/qr/qr-mpm-refund
HTTP MethodPOST
Versionv1.0
SNAP Service Code78

Request Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 formatAirpay Shopee accepts refund only at 06:00 to 23:55 GMT+7
X-SIGNATUREStringMCreated using symmetric signature HMAC_SHA512 algorithm
AuthorizationStringMRepresents access_token of a request; string starts with keyword “Bearer ” followed by access_token. Can get this token from Access Token B2B response.
X-PARTNER-IDStringMUnique identifier for caller
X-EXTERNAL-IDStringMAlphanumeric string. We suggest merchant to use UUID format. The value should be unique.
In case of timeout, merchant can do:
  1. Use this value in get status API to get status transaction or
  2. Retry this request with the same X-EXTERNAL-ID and request body to avoid creating duplicate transaction
The value should also be the same as request_body.partnerRefundNo
CHANNEL-IDStringMMandatory 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

Field NameField TypeMandatoryField Description
merchantIdString (64)MMerchant identifier that is unique per each merchant.
subMerchantIdString(32)OSub merchant ID
externalStoreIdString(64)CExternal store ID
originalPartnerReferenceNoString(64)MTransaction identifier on service consumer system. For e.g : MerchantOrderId
originalReferenceNoString(64)OTransaction identifier on service provider system. For e.g: GopayOrderId

*either originalExternalId or OriginalReferenceNo need to be filled

If both fields have value, will use originalReferenceNo as the main identifier.

originalExternalIdString(32)OOriginal customer reference number
partnerRefundNoString(64)MReferenceNumber from PJP AIS for the refund.
This value should be filled with the same value as X-EXTERNAL-ID
refundAmountObjectOrefundAmount object, if amount not set, system will treat as full refund request.
refundAmount.valueString (16,2)ONet 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.

Airpay Shopee only supports full refund
refundAmount.currencyString (2)OCurrency.
reasonString (256)OReason for the refund.
additionalInfoObjectOAdditional Information if merchant’s need to pass.
{
   "merchantId":"00007100010926",
   "subMerchantId":"310928924949487",
   "externalStoreId":"124928924949487",
   "originalPartnerReferenceNo":"2020102900000000000001",
   "originalReferenceNo":"2020102977770000000009",
   "originalExternalId":"10052019",
   "partnerRefundNo":"239850918204981205970",
   "refundAmount":{
      "value":"10000.00",
      "currency":"IDR"
   },
   "reason":"Customer complain",
   "additionalInfo":null
}

Response Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
Content-type:application/json
X-TIMESTAMP:2024-03-19T14:30:00+07:00

Response Body

Field NameField TypeMandatoryField Description
responseCodeString (7)MResponse code
responseMessageString(150)MResponse description
originalPartnerReferenceNoString(64)OOriginal transaction identifier on service consumer system
originalReferenceNoString(64)COriginal transaction identifier on service provider system
originalExternalIdString(32)OOriginal customer reference number
referenceNoString(64)MreferenceNumber
refundAmountObjectOrefundAmount object
refundAmount.valueString (ISO 4217) (16,2)ONet 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

refundAmount.currencyString (2)OCurrency.
partnerRefundNoString(64)MUnique identifier of refund transaction generated by client.

Merchant refund ID. If not passed then Midtrans creates a new one. It is recommended to use this parameter to avoid double refund attempts. Allowed characters are alphabets, numbers, dash (-), and underscore (_).

refundTimeString(25)MRefund time. ISO 8601
additionalInfoObjectOAdditional Information if merchant’s need to pass.
{
   "responseCode":"2007800",
   "responseMessage":"Request has been processed successfully",
   "originalPartnerReferenceNo":"2020102900000000000001",
   "originalReferenceNo":"2020102977770000000009",
   "originalExternalId":"10052019",
   "referenceNo":"REF993883",
   "partnerRefundNo":"239850918204981205970",
   "refundAmount":{
      "value":"10000.00",
      "currency":"IDR"
   },
   "refundTime":"2020-12-21T17:21:41+07:00",
   "additionalInfo":null
}

List of Response code

Response CodeHTTP Status CodeResponse Message
2007800200Success
4007802400Invalid Mandatory Field merchantId
4017800401Unauthorized. Signature
4017801401Invalid Token (B2B)
4037814403Insufficient Funds
4047800404Invalid Transaction Status
4047801404Transaction Not Found
4047813404Invalid amount or user balance exceeded.
4037802403Exceeds Transaction Amount Limit
4097801409Duplicate Transaction
4057801405Merchant refund request exceeds the allowed refund window.
5007801500Internal Server Error
5047800504Timeout

Initiating refund for GoPay Tokenization (Pre Auth) transaction

This section will describe how a merchant can initiate refunds for GoPay Tokenization (Pre Auth) transactions.

Path/{version}/auth/refund
HTTP MethodPOST
Versionv1.0
SNAP service code69

Request Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
X-SIGNATUREStringMCreated using symmetric signature HMAC_SHA512 algorithm
AuthorizationStringMRepresents access_token of a request; string starts with keyword “Bearer ” followed by access_token. Can get this token from Access Token B2B API response.
X-PARTNER-IDStringMUnique identifier for caller (client_id)
X-EXTERNAL-IDStringMAlphanumeric string. We suggest merchant to use UUID format. The value should be unique.
In case of timeout, merchant can do:
  1. Use this value in get status API to get status transaction or
  2. Retry this request with the same X-EXTERNAL-ID and request body to avoid creating duplicate transaction
CHANNEL-IDStringMMandatory 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

Field NameField TypeMandatoryField Description
originalReferenceNoString(64)CTransaction identifier on service provider system. For e.g: GopayOrderId

Note: either originalExternalId or OriginalReferenceNo need to be filled

If both fields have value, will use originalReferenceNo as the main identifier.
originalPartnerReferenceNoString (64)MMerchant order-id
partnerRefundNoString(64)MReferenceNumber from PJP AIS for the refund.
refundAmountObjectORefund amount
refundAmount.valueString (ISO4217)MNet 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
refundAmount.currencyString(3)MRefund amount currency
reasonString(256)OReason for the refund. For Gopay, this field will be shown on Gopay Order History
additionalInfo
additionalInfo.originalExternalIdString (36)CIf 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",
   "partnerRefundNo":"asdv-asdasdv-addasd-1231ewqqw-aaaa",
   "refundAmount":{
  	"value":"12345678.00",
  	"currency":"IDR"
   },
   "reason":"aReason",
   "additionalData":{
          "originalExternalId":"aId",
}
}

Response Header

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
Content-type: application/json
X-TIMESTAMP: 2024-03-19T14:30:00+07:00

Response Body

Field NameField TypeMandatoryField Description
responseCodeString (7)MError code to specify the error returned.
responseMessageString (150)MDebug message to provide more information.
originalReferenceNoString (256)OTransaction identifier on service provider system. For e.g: GopayOrderId
partnerRefundNoString (64)OPJSP's refund identifier. Used to trace the capture when there's any issue occurred.
refundNoString (64)MReference number
refundTimeString(25)MThe time when the payment will be automatically expired. Using ISO 8601 format
refundAmountObjectORefund amount
refundAmount.valueString (16,2)OTransaction 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

refundAmount.currencyStringOCurrency. For e.g: IDR
{
   "responseCode":"20054000",
   "responseMessage":"Request has been processed successfully",
    "originalReferenceNo":"2020102900000000000001",
   "refundNo":"asdv-asdasdv-addasd-1231ewqqw-aaaa",
    "partnerRefundNo":"refund0123",
   "refundTime":"2023-07-03T10:36:17+07:00",
   "refundAmount":{
  	"value":"12345678.00",
  	"currency":"IDR"
   }
}
{
   "responseCode":"4006901",
   "responseMessage":"There is some issue with the transaction request"
}

List of Response code

Response CodeHTTP Status CodeResponse Message
2006900200Success
4006902400Invalid Mandatory Field {Field Name}
4016900401Unauthorized. Auth token required
4016901401Invalid Token (B2B)
4036902403Exceeds Transaction Amount Limit
4036914403Insufficient Funds
4036515403Transaction Not Permitted.[reason].
5006901500Internal Server Error
5046900504Timeout

Handling Order "Post-Process" in Refund Flow (Race-Condition)

When calling our Refund API, there might be a possibilities for you to encounter "error-"code":"2007" "cause":"Refund not processable when payment is in progress" , this scenario will happens if you make a call while the order "post-process" is still running. Our "post-process" is needed to ensure that any next action on behalf of that order (such as Refund) is secure. This "post-process" usually takes in a split micro-seconds.

In a condition where you have a use cases that needs you to initiate Refund right after the order settled, please implement a retry mechanism for calls that encountered with "error-"code":"2007". When you encounter this error, please set multiple layer of "backoff" mechanism where you

  • Retry the request after 1 second
  • Then if still encountered with this error, retry after 5 seconds, and so on

This approach ensures that your application interacts smoothly with our API once order processing is complete.