Skip to main content

Migration from UTpay

This guide helps you move from the Legacy (UTpay) API to the Merchant API V1. The V1 API offers a simpler auth model, richer response objects, and consistent minor-unit amounts.

note

You do not have to migrate. The Legacy API remains fully supported indefinitely. Migrate only when it is convenient for your development cycle.

Side-by-Side Comparison

Authentication

Legacy APIMerchant API V1
OrdersSHA-512 body signatureX-API-Key header
DisbursementsRSA X-SIGNATURE headerX-API-Key header
Credentialslegacy_client_id + legacy_client_secret + RSA keyapi_key only

V1 change: Remove all signature computation. Add X-API-Key header to every request.

Amount Format

Legacy APIMerchant API V1
Create ordertotalAmount: 50000 (IDR 50,000)amount_minor: 5000000 (IDR 50,000)
Disbursement requestrequestAmount: 500000 (IDR 500,000)amount_minor: 50000000
Balance"5000000.00" (decimal string)5000000000 (integer minor units)

V1 change: Multiply all IDR amounts by 100 on the way in. Divide by 100 on the way out.

URL Path Changes

Legacy pathV1 pathMethod
POST /api/order/createPOST /v1/ordersCreate order
POST /api/order/queryGET /v1/orders/:ref_codeGet order
POST /api/disbursement/get-balanceGET /v1/balanceWallet balance
POST /api/disbursement/createPOST /v1/disbursements (channel: BANK)Bank disbursement
POST /api/disbursement/create-ewalletPOST /v1/disbursements (channel: EWALLET)E-wallet disbursement
POST /api/disbursement/queryGET /v1/disbursements/:ref_codeGet disbursement

Request Field Mapping

Create Order

Legacy fieldV1 fieldNotes
clientId(removed)Identified by API key
orderIdmerchant_order_idSame purpose
totalAmountamount_minor× 100
paymentTypepayment_methodSame values (QRIS, BANK_TRANSFER)
signature(removed)Auth via header
customerNamecustomer_namesnake_case
customerEmailcustomer_emailsnake_case
customerPhonecustomer_phonesnake_case
notifyUrlnotify_urlsnake_case
returnUrlreturn_urlsnake_case

Create Bank Disbursement

Legacy fieldV1 fieldNotes
clientId(removed)Auth via header
orderIdidempotency_keySame purpose
bankCodebank_short_codeSame values
accountNumberaccount_numbersnake_case
accountNameaccount_namesnake_case
requestAmountamount_minor× 100
channelchannel: "BANK"Add explicitly

Response Shape

Order

Legacy fieldV1 field
data.refCodedata.ref_code
data.orderIddata.merchant_order_id
data.totalAmountdata.amount_minor (÷ 100 to convert)
data.transactionTimedata.created_at (ISO 8601, UTC)
data.paidAtdata.paid_at (ISO 8601, UTC)
data.qrStringdata.qris_string

Webhook

Legacy fieldV1 field
refCoderef_code
orderIdmerchant_order_id
totalAmount (IDR int)amount_minor (minor units)
statusstatus + event
paidAt (WIB string)paid_at (ISO 8601 UTC)

Migration Checklist

Use this checklist to migrate without downtime:

  • Obtain your V1 api_key from the merchant dashboard
  • Run both integrations in parallel: Legacy for existing orders, V1 for new orders
  • Update create-order code: use X-API-Key, rename fields, multiply amounts × 100
  • Update webhook handler: new field names, divide amount_minor ÷ 100 for display
  • Update disbursement code: use X-API-Key, rename fields, update channel field
  • Update balance display: V1 returns balance_minor (integer), ÷ 100 for IDR
  • Test full flow: create order → pay → receive webhook → query status
  • Test disbursements: get balance → create → query
  • Switch all new traffic to V1
  • Monitor for errors for 1 week
  • Notify your account manager to disable Legacy credentials (optional)

Frequently Asked Questions

Will my orderId (Legacy) conflict with merchant_order_id (V1)?
No. These are stored separately. You can have the same string as both a legacy orderId and a V1 merchant_order_id for different orders.

Can I use the Legacy API for some orders and V1 for others?
Yes. Both APIs are fully active simultaneously. The source_api field on orders in the Admin Dashboard indicates which API was used.

What happens to my RSA key pair after migration?
Nothing — your keys remain stored. You only need them as long as you use the Legacy API.

Do settlement calculations change when I migrate?
No. MDR, fees, and net payout calculations are identical regardless of which API created the order.