Environment Variable :
https://app.byte-stack.net
https://apigw.ovo.id
All the APIs mentioned are to follow the standard header format mentioned here, unless stated otherwise
Parameter | Description | Attribute | Example |
---|---|---|---|
Content-Type | String represents indicating the media type of the resource | Mandatory | application/json, application/pdf |
Authorization | Represents access_token of a request; string starts with keyword “Bearer ” followed by access_token Not Applicable for B2B Access Token API |
Conditional | Bearer eyJraWQiOi...Jzc29zIiwiY |
X-CLIENT-KEY | Client's client_id. Use this for these APIs below
|
Conditional | testdynamicqris |
X-PARTNER-ID | Client's client_id. Use this for these APIs below
|
Conditional Need to change to QRIS MPM API Unique ID for a partner |
testdynamicqris |
X-TIMESTAMP | Client's current local time in yyyy-MM-ddTHH:mm:ssTZD format | Mandatory Client's current local time in yyyy-MM-ddTHH:mm:ssTZD format |
|
X-SIGNATURE | Use Asymmetric B2B Token request Use Symmetric Generate QR Refund Inquiry Status Callback |
Mandatory | Please check Signature Section |
X-EXTERNAL-ID | Unique ID to avoid duplication. ID reset for every 24 hours. String (36) | Mandatory | |
CHANNEL-ID | PJP’s channel id Device identification on which the API services is currently being accessed by the end user (customer) |
Mandatory |
Signature asymmetric is used by OVO to verify that your access token request is not altered by attackers. Generate Signature Asymmetric for Header of Access Token B2B
SHA256withRSA is used to generate the signature with your Private Key as the key.
/*
How to use:
- Configure the client ID via request headers with key as x-client-key.
- Configure the private key via environment variable with key as {clientID}_private_key.
- Script will generate / replace environment variables listed in the Output section.
Output (Environment variables):
- gen_signature -> add to X-Signature headers
- gen_timestamp -> add to X-Timestamp headers
*/
eval( pm.environment.get('pmlib_code') )
var moment = require('moment')
const clientID = pm.environment.get("clientID")
var privateKey = pm.environment.get("_private_key")
const timestamp = moment().format("YYYY-MM-DDThh:mm:ss.SSSZ")
console.log("clientID: " + clientID)
console.log("privateKey: " + privateKey)
console.log("timestamp: " + timestamp)
const msg = `${clientID}|${timestamp}`
console.log("msg: " + msg)
var CryptoJS = require("crypto-js")
const hashedMsg = CryptoJS.SHA256(msg)
console.log("hashedMsg: " + hashedMsg)
var sig = new pmlib.rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"})
privateKey = pmlib.rs.KEYUTIL.getKey(privateKey)
sig.init(privateKey)
const hash = sig.signString(msg)
console.log("hash: " + hash)
pm.environment.set("gen_timestamp", timestamp)
pm.environment.set("gen_signature", hash)
Signature is used to verify that your open API service request is not altered by attackers.
SHA-512 HMAC is used to generate the signature with your Client Secret as the key.
/*
How to use:
- Configure the client ID via request headers with key as x-partner-id.
- Configure the access token via request headers with key as Authorization and format of value as Bearer {access_token}.
- Configure the secret key via environment variable with key as {clientID}_secret_key.
- Script will generate / replace environment variables listed in the Output section.
Output (Environment variables):
- gen_signature -> add to X-Signature headers
- gen_timestamp -> add to X-Timestamp headers
*/
eval( pm.globals.get('pmlib_code') )
var moment = require('moment')
var CryptoJS = require("crypto-js")
const clientID = pm.environment.get('clientID');
const accessToken = pm.environment.get("access_token");
const timestamp = moment().format("YYYY-MM-DDThh:mm:ss.SSSZ")
const body = pm.request.body.raw
const fullPath = pm.request.url.getPathWithQuery()
const method = pm.request.method
var secret_key = pm.environment.get("_secret_key")
console.log("clientID: " + clientID)
console.log("accessToken: " + accessToken)
console.log("timestamp: " + timestamp)
console.log("body: " + body)
console.log("fullPath: " + fullPath)
console.log("method: " + method)
console.log("secret_key: " + secret_key)
const hashedBody = CryptoJS.SHA256(body).toString()
const finalBody = hashedBody.toLowerCase()
console.log("hashedBody: " + hashedBody)
console.log("finalBody: " + finalBody)
const msg = `${method}:${fullPath}:${accessToken}:${finalBody}:${timestamp}`
console.log("msg: " + msg)
const hash = CryptoJS.HmacSHA512(msg, secret_key).toString()
console.log("hash: " + hash)
pm.environment.set("gen_timestamp", timestamp)
pm.environment.set("gen_signature", hash)
pm.environment.set("api", "/OVOSNAP/v1.0/debit/payment-host-to-host")
For Openssl version 1.x.x
openssl genrsa -out private.pem 4096
For Openssl version 3.x.x and above
openssl genrsa -traditional -out private.pem 4096
openssl rsa -in private.pem -RSAPublicKey_out -out public.pem
This API will be used by Merchants to trigger the transactional API. Before generating the token, partners are requested to address this as a requirement, so OVO can configure the necessary.
As per Bank Indonesia requirements, the token expiry for B2B token must be 15 minutes.
/OVOSNAP/v1.0/access-token/b2b
73
Name | Mandatory | Type | Length | Description |
---|---|---|---|---|
grantType | M | String | "client_credentials”: The client can request an access token using only its client credentials (or other supported means of authentication) when the client is requesting access to the protected resources under its control |
{
"grantType": "client_credentials"
}
Name | Type | Description |
---|---|---|
responseCode | String | Response code |
responseMessage | String | Response description |
accessToken | String | A string representing an authorization issued to the client that used to access protected resources |
tokenType | String | The access token type provides the client with the information required to successfully utilize the access token to make a protected resource request (along with type-specific attributes).
Token Type Value:
|
expiresIn | String | Time in seconds |
additionalInfo | Object | Same as in request |
{
"responseCode": "2007300",
"responseMessage": "Successful",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiZjFmM2Q3ZS1kOTA3LTRkOWItODJlNC02Y2IxZGYxOTBlOWUiLCJjbGllbnRJZCI6IjZhZTk1N2M0LTI4NjMtNDcxMy1hY2NlLWJhMTJkZTYzNmNmYyIsIm5iZiI6MTYxMTQ2ODg1NiwiZXhwIjoxNjExNDY5NzU2LCJpYXQiOjE2MTE0Njg4NTZ9.-7HRhcyEh4y0qsG2H3DRdu0AeYv3MEJHfWRKhRBYcNU",
"tokenType": "Bearer",
"expiresIn": "900",
"expireIn": "2023-05-15T09:12:24Z",
"additionalInfo": {}
}
There are two ways in which a partner can refresh the expired tokens
Response Code : HTTP status code + service code + case code
HTTP Status | Service Code | Case Code | Response Message | Description |
---|---|---|---|---|
200 | Any | 00 | Success | Success |
400 | Any | 00 | Bad Request | General request failed error, including message parsing failed. |
400 | Any | 01 | Invalid Field Format | Invalid format |
400 | Any | 02 | Invalid Mandatory Field | Missing or invalid format on mandatory field |
401 | Any | 01 | Invalid Token (B2B) | Token found in request is invalid (Access Token Not Exist, Access Token Expiry) |
Call Flow: H2H client to OVO backend
/OVOSNAP/v2.0/qr/qr-mpm-generate
https://app.byte-stack.net
https://apigw.ovo.id
47
Name | Mandatory | Type | Length | Description | |
---|---|---|---|---|---|
terminalId | M | String | 16 | Terminal Identification | |
merchantId | M | String | 64 | Merchant identifier that is unique per each merchant | |
amount | M | Object | |||
value | M | String | 16,2 | Net amount of the transaction e.g. 10000.00 | |
currency | M | String (ISO4217) | 3 | Currency Ex: IDR |
|
feeAmount | O | Object | |||
value | O | String | 16,2 | Transaction fee | |
currency | O | String (ISO4217) | 3 | Currency | |
partnerReferenceNo | M | String | 64 | Transaction identifier on service consumer system (traceNo) We can generate it based on UUID |
|
subMerchantId | O | String | 32 | Sub merchant ID | |
storeId | O | String | 64 | Unique shop/store id in merchant side | |
additionalInfo | M | Object | Additional information | ||
deviceId | M | String | 64 | Customer Device ID Can be Hardcoded/Static String |
|
channel | M | String | 64 | Channel ID String = “OVO” |
|
transactionDate | M | String | 6 | YYMMDD format | |
allowedSources | M | String | *format is defined below |
*allowedSources : format will be an bitmap, ie, each position in a bitmap will represent one
SOF and if the value is 1, it means that particular SOF is allowed, and if it's 0, it means that
particular SOF is not allowed for making the payment
{
"terminalId": "13000004",
"merchantId": "DBCFJKTLPKN0001",
"amount": {
"value": "10000.00",
"currency": "IDR"
},
"feeAmount": {
"value": "0.00",
"currency": "IDR"
},
"partnerReferenceNo": "234567890123",
"subMerchantId": "",
"storeId": "abcd",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "ovo",
"transactionDate": "191225",
"allowedSources": "100"
}
}
Name | Type | Description | |
---|---|---|---|
responseCode | String | Response code = HTTP status code + service code + case code | |
responseMessage | String | Response description | |
referenceNo | String | Transaction identifier on service provider system. Must be filled upon successful transaction |
|
partnerReferenceNo | String | Transaction identifier on service consumer system | |
qrContent | String | QR String MPM. If qrContent is null, then qrUrl or qrImage must be filled. |
|
merchantName | String | Merchant Name | |
storeId | String | Unique shop id on the merchant side. | |
terminalId | String | Terminal Identification | |
additionalInfo | Object | Same as in request | |
deviceId | String | Same as in request | |
channel | String | Same as in request | |
transactionDate | String | Same as in request | |
batchNo | String | Batch Number | |
expiry | Integer | In seconds - QR Expiry window |
{
"responseCode": "2004700",
"responseMessage": "Successful",
"referenceNo": "H2H3c17c56de31847249edfcca0918d",
"partnerReferenceNo": "TRX-ASK3XCA",
"qrContent": "00020101021226580006id.ovo01189360091200000035470215lXglBoWv1FKdldj0303UMI51440015ID.OR.GPNQR.WWW0214ID2021075018580303UMI520415205303360540410005802ID5918Dretail Store Satu6008Meulaboh610523350623105074IIwC6G07167sWt1OwfUMzWb7SF6304D8F5",
"merchantName": "DretailStore001",
"storeId": "abcd",
"terminalId": "11762601",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "ovo",
"transactionDate": "230504",
"batchNo": "cF9M96",
"expiry": 75
}
}
{
"responseCode": "4044708",
"responseMessage": "Invalid Merchant"
}
HTTP Status | Service Code | Case Code | Response Message | Description |
---|---|---|---|---|
200 | 47 | 00 | Success | Success |
400 | 47 | 00 | Bad Request | General request failed error, including message parsing failed. |
400 | 47 | 01 | Invalid Field Format | Invalid format |
400 | 47 | 02 | Invalid Mandatory Field | Missing or invalid format on mandatory field |
404 | 47 | 08 | Invalid Merchant | Merchant is invalid (blocked/not registered/not active) |
404 | 47 | 18 | Invalid QRIS Merchant | Not PTEN Registered |
409 | 47 | 00 | Duplicate {} | Usually like `Duplicate x-external-id` or `partnerReferenceNo` |
429 | 47 | 00 | Too Many Request | Pending Transaction Limit Reached. Try it after some time. Need to settle the pending transaction first before generating the new QR. |
500 | 47 | 00 | General Error | Internal errors happen on OVO service that don't relate to the connectivity. |
500 | 47 | 01 | Internal Server Error | Internal errors happen on OVO service while trying to get the response from internal dependency. |
500 | 47 | 04 | Timeout | Request Timeout |
/OVOSNAP/v2.0/qr/qr-mpm-query
https://app.byte-stack.net
https://apigw.ovo.id
51
Name | Mandatory | Type | Length | Description | |
---|---|---|---|---|---|
originalReferenceNo | M | String | 64 | Original transaction identifier on service provider system | |
originalPartnerReferenceNo | M | String | 64 | Original transaction identifier on service consumer system | |
serviceCode | M | String | 2 | Transaction type indicator (service code of the original transaction request) Service Code 47 |
|
merchantId | M | String | 64 | Merchant identifier that is unique per each merchant | |
subMerchantId | O | String | 32 | Sub merchant ID | |
externalStoreID | O | String | 64 | External Store ID | |
additionalInfo | M | Object | Additional information | ||
deviceId | M | String | Customer Device ID Can be Hardcoded/Static String |
||
channel | M | String | Channel ID String = "OVO" |
||
terminalId | M | String | 16 | Terminal Identification |
{
"originalReferenceNo": "H2H3c17c56de31847249edfcca0918d",
"originalPartnerReferenceNo": "TRX-ASK3XCA",
"serviceCode": "47",
"merchantId": "DretailStore001",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "OVO",
"terminalId": "13000004"
}
}
Name | Type | Description | ||
---|---|---|---|---|
responseCode | String | Response code | ||
responseMessage | String | Response description | ||
originalReferenceNo | String | Original transaction identifier on service provider system. Must be filled upon successful transaction | ||
originalPartnerReferenceNo | String | Original transaction identifier on service consumer system | ||
serviceCode | String | Transaction type indicator (service code of the original transaction request) Service Code 47 |
||
latestTransactionStatus | String | 00 - Payment Success 01 - Refund Pending 03 - Payment Pending 04 - Refund Success 06 - Transaction Failed |
||
transactionStatusDesc | String | Description status transaction | ||
paidTime | String | Transaction date - ISO-8601 Format Format: yyyyMMddHHmmss |
||
terminalId | String | Terminal Identification | ||
amount | Object | |||
value | String | Net amount of the transaction. If it's IDR then the value includes 2 decimal digits. e.g. IDR 10000,- will be placed with 10000.00 |
||
currency | String | Currency | ||
feeAmount | Object | |||
value | String | Net amount of the transaction. If it's IDR then the value includes 2 decimal digits. e.g. IDR 10000,- will be placed |
||
currency | String | Currency | ||
additionalInfo | Object | |||
deviceId | String | Same as in request | ||
channel | String | Same as in request | ||
gracePeriod | Integer | In Seconds - ‘x’ - next inquiry call for this transaction should be triggered to OVO backend, after ‘x’ seconds. | ||
batchNo | String | Batch Number from the first QR Generation | ||
merchantId | String | Same as in request | ||
userName | String | Masked user’s full name | ||
merchantPan | String | mpan for the merchant | ||
customerPan | String | cpan for the customer | ||
phoneNumber | String | Masked Phone Number Ex: \*\*\*\* \*\*\*\* 2001 | ||
issuerName | String | Issuer Name ex. OVO, GOPAY, etc. | ||
transactionId | String | Transaction ID is from BE, to be used for refund (Should be unique for each transaction). EDC has to store this transactionId and map it with the transactions. | ||
transactionSummary | ||||
points | String | if user pays with OVO points | ||
cash | String | if user pays with OVO cash | ||
payLater | String | if user pays with OVO paylater |
{
"responseCode": "2005100",
"responseMessage": "Successful",
"originalReferenceNo": "H2H3c17c56de31847249edfcca0918d",
"originalPartnerReferenceNo": "TRX-SK3XCA",
"serviceCode": "47",
"latestTransactionStatus": "00",
"transactionStatusDesc": "Payment Success",
"paidTime": "2023-05-09T18:02:27",
"terminalId": "213141251124",
"amount": {
"value": "10000.00",
"currency": "IDR"
},
"feeAmount": null,
"additionalInfo": {
"deviceId": "0001100009537395",
"channel": "ovo",
"gracePeriod": 5,
"batchNo": "cF9UXY",
"merchantId": "DretailStore001",
"userName": "H**** L*******",
"merchantPan": "9630570000051061610",
"customerPan": "",
"phoneNumber": "********2580",
"issuerName": "OVO",
"transactionId": "7178",
"transactionSummary": {
"points": "0",
"cash": "20000",
"payLater": "0"
}
}
}
Response Code : HTTP status code + Transaction Inquiry service code + case code
HTTP Status | Service Code | Case Code | Response Message | Description |
---|---|---|---|---|
200 | 51 | 00 | Success | Success |
400 | 51 | 00 | Bad Request | General request failed error, including message parsing failed. |
400 | 51 | 01 | Invalid Field Format | Invalid format |
400 | 51 | 02 | Invalid Mandatory Field | Missing or invalid format on mandatory field |
404 | 51 | 01 | Transaction Not Found | Transaction Not Found |
404 | 51 | 08 | Invalid Merchant | Merchant is invalid (blocked/not registered/not active) |
404 | 51 | 17 | Invalid Terminal | Terminal is invalid (blocked/not registered/not active) |
409 | 51 | 00 | Duplicate {} | Usually like `Duplicate x-external-id` or `partnerReferenceNo` |
500 | 51 | 00 | General Error | Internal errors happen on OVO service that don't relate to the connectivity. |
500 | 51 | 01 | Internal Server Error | Internal errors happen on OVO service while trying to get the response from internal dependency. |
500 | 51 | 04 | Timeout | Request Timeout |
.../v1.0/qr/qr-mpm-notify
52
Name | Mandatory | Type | Length | Description | |
---|---|---|---|---|---|
originalReferenceNo | M | String | 64 | Transaction identifier on service provider system | |
originalPartnerReferenceNo | O | String | 64 | Transaction identifier on service consumer system | |
latestTransactionStatus | M | String | 2 | 00 - Payment Success 06 - Transaction Failed |
|
transactionStatusDec | O | String | 50 | Description Status Transaction | |
customerNumber | M | String | 64 | Customer Account Number | |
destinationNumber | O | String | 25 | Destination account number | |
destinationAccountName | O | String | 25 | Destination account name | |
amount | M | Object | |||
value | M | String | 16,2 | Net amount of the transaction eg. IDR 10000.00 | |
currency | M | String | 3 | Currency Example: IDR |
|
externalStoreId | O | String | 64 | External Store ID | |
additionalInfo | M | ||||
deviceId | M | String | 64 | ||
channel | M | String | 64 | ||
gracePeriod | M | Integer | 16 | In Seconds - ‘x’ - next inquiry call for this transaction should be triggered to the OVO backend, after ‘x’ seconds. | |
terminalId | M | Integer | 8 | Terminal ID | |
userName | M | String | 32 | Masked ovo user’s full name | |
merchantPan | M | String | 32 | Merchant Pan for the merchant | |
customerPan | O | String | 32 | Customer Pan for the customer | |
issuerName | O | String | 15 | Issuer Name ex. OVO, GOPAY, etc. | |
transactionId | M | String | 32 | Transaction ID is from BE, to be used for refund (Should be unique for each transaction). H2H/POS have to store this transactionId and map it with the transactions. |
{
"originalReferenceNo": "H2H784c1b556971470788fe1d80c6de",
"originalPartnerReferenceNo": "TRX-ASacaSA",
"latestTransactionStatus": "00",
"transactionStatusDesc": "Payment Success",
"customerNumber": "********0001",
"destinationNumber": "",
"destinationAccountName": "",
"amount": {
"value": "10000.00",
"currency": "IDR"
},
"externalStoreId": "",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "ovo",
"gracePeriod": 5,
"terminalId": "11762601",
"userName": "H**** L*******",
"merchantPan": "936009120000003547",
"customerPan": "",
"issuerName": "OVO",
"transactionId": "7136"
}
}
Name | Type | Description | |
---|---|---|---|
responseCode | String | Response code | |
responseMessage | String | Response description | |
additionalInfo | Object | ||
deviceId | String | Same as in request | |
channel | String | Same as in request |
{
"responseCode": "2005200",
"responseMessage": "Request has been processed successfully",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "mobilephone"
}
}
/OVOSNAP/v2.0/qr/qr-mpm-refund
https://app.byte-stack.net
https://apigw.ovo.id
78
Name | Mandatory | Type | Length | Description | |
---|---|---|---|---|---|
originalReferenceNo | O | String | 64 | Original transaction identifier on service provider system | |
originalPartnerReferenceNo | M | String | 64 | Original transaction identifier on service consumer system | |
merchantId | M | String | 64 | Merchant identifier that is unique per each merchant | |
subMerchantId | O | String | 32 | Sub Merchant ID | |
externalStoreId | O | String | 64 | External Store ID | |
partnerRefundNo | M | String | 64 | ReferenceNumber from PJP AIS for the refund. | |
refundAmount | M | Object | |||
value | M | String | 16,2 | Net amount of the refund | |
currency | M | String | 3 | Currency | |
reason | O | String | 256 | Refund reason | |
additionalInfo | M | Object | |||
deviceId | M | String | 64 | Customer Device ID Can be Hardcoded/Static String |
|
channel | M | String | 64 | Customer Channel String = “OVO” |
|
terminalId | M | String | 16 | Terminal Identification | |
batchNo | M | String | 64 | Batch Number from the first QR Generation Getting the value from Generate QR or Transaction Inquiry |
|
transactionId | M | String | 32 | Transaction ID is from BE, to be used for refund (Should be unique for each transaction). H2H/POS have to store this transactionId and map it with the transactions. |
{
"originalPartnerReferenceNo": "H2H784c1b556971470788fe1d80c6de",
"originalReferenceNo": "TRX-ASacaSA",
"merchantId": "DretailStore001",
"partnerRefundNo": "REFUND-TRX-SK3XCA",
"subMerchantId": "310928924949487",
"externalStoreId": "124928924949487",
"refundAmount": {
"value": "1000.00",
"currency": "IDR"
},
"reason": "Customer complain",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "mobilephone",
"terminalId": "11762601",
"batchNo": "cF9UXY",
"transactionId": "7178"
}
}
Name | Type | Description | |
---|---|---|---|
responseCode | String | Response code | |
responseMessage | String | Response description | |
originalPartnerReferenceNo | String | Original transaction identifier on service provider system. Must be filled upon successful transaction | |
originalReferenceNo | String | Original transaction identifier on service consumer system | |
referenceNo | String | referenceNumber | |
partnerRefundNo | String | Same as in request | |
refundAmount | Object | ||
value | String | Same as in request | |
currency | String | Same as in request | |
refundTime | String | Refund time. ISO 8601 | |
additionalInfo | Object | ||
deviceId | String | Same as in request | |
channel | String | Same as in request | |
terminalId | String | Terminal Identification | |
merchantId | String | Same as in request | |
merchantName | String | Same as in request | |
phoneNumber | String | Masked Phone Number Ex: **** **** 2001 |
|
merchantPan | String | mpan for the merchant | |
customerPan | String | cpan for the customer | |
userName | String | Masked user’s full name | |
issuerName | String | Issuer Name ex. OVO, GOPAY, etc. |
{
"responseCode": "2007800",
"responseMessage": "Request has been processed successfully",
"originalPartnerReferenceNo": "2020102900000000000001",
"originalReferenceNo": "2020102977770000000009",
"referenceNo": "",
"partnerRefundNo": "239850918204981205970",
"refundAmount": {
"value": "10000.00",
"currency": "IDR"
},
"refundTime": "2023-05-09T18:02:27",
"additionalInfo": {
"deviceId": "12345679237",
"channel": "mobilephone",
"terminalId": "13000004",
"merchantId": "DBCFJKTLPKN0001",
"merchantName": "Delicio LK",
"phoneNumber": "89********",
"merchantPan": "9630570000051061610",
"customerPan": "9360091800051061610",
"userName": "te********",
"issuerName": "OVO"
}
}
Response Code : HTTP status code + Refund service code + case code
HTTP Status | Service Code | Case Code | Response Message | Description |
---|---|---|---|---|
200 | 78 | 00 | Success | Success |
202 | 78 | 00 | Request in Progress | Refund pending and is still being processed |
400 | 78 | 00 | Bad Request | General request failed error, including message parsing failed. |
400 | 78 | 01 | Invalid Field Format | Invalid format |
400 | 78 | 02 | Invalid Mandatory Field | Missing or invalid format on mandatory field |
403 | 78 | 03 | Suspected Fraud | Suspected fraud from OVO Internal Risk checking |
403 | 78 | 24 | Refund Expired | Refunds will be allowed on the same day. |
404 | 78 | 01 | Transaction Not Found | Transaction Not Found |
404 | 78 | 08 | Invalid Merchant | Merchant is invalid (blocked/not registered/not active) |
404 | 78 | 13 | Invalid Amount | Amount that wants to be refunded is not the same as the success payment |
404 | 78 | 17 | Invalid Terminal | Terminal is invalid (blocked/not registered/not active) |
409 | 78 | 00 | Duplicate {} | Usually like `Duplicate x-external-id` or `partnerReferenceNo` |
500 | 78 | 00 | General Error | Internal errors happen on OVO service that don't relate to the connectivity. |
500 | 78 | 01 | Internal Server Error | Internal errors happen on OVO service while trying to get the response from internal dependency. |
500 | 78 | 04 | Timeout | Request Timeout |