openapi: 3.0.3 info: title: Midtrans Payment Card Tokenization Core API API description: 'A representative OpenAPI description of the Midtrans payment platform, an Indonesian payment gateway (part of the GoTo Group). It covers Snap (hosted checkout), the Core API (charge and transaction lifecycle), card and GoPay tokenization, Payment Link, recurring Subscriptions, and Iris disbursement / payouts. Hosts vary by product. The default servers below are the Core API / Payment Link / Subscription hosts (api.midtrans.com and api.sandbox.midtrans.com). Snap runs on app.midtrans.com and Iris runs on app.midtrans.com/iris; those paths declare their own path-level `servers` override so the full URL is always unambiguous. Authentication is HTTP Basic: your Server Key is the username and the password is empty (`Authorization: Basic base64(SERVER_KEY:)`). The two card tokenization endpoints instead use the public Client Key passed as a query parameter, and Iris uses its own creator / approver API key over HTTP Basic. This document was authored by API Evangelist from Midtrans'' public documentation and official Postman collection; request / response bodies are modeled representatively rather than exhaustively.' version: '1.0' contact: name: Midtrans url: https://midtrans.com license: name: Proprietary url: https://midtrans.com servers: - url: https://api.midtrans.com description: Core API / Payment Link / Subscription - Production - url: https://api.sandbox.midtrans.com description: Core API / Payment Link / Subscription - Sandbox security: - serverKeyAuth: [] tags: - name: Core API description: Charge and manage the lifecycle of a transaction. paths: /v2/charge: post: operationId: chargeTransaction tags: - Core API summary: Charge a transaction description: Performs a charge for the chosen `payment_type`. Supported types include credit_card, bank_transfer (Permata / BCA / BNI / BRI virtual account), echannel (Mandiri Bill), gopay, shopeepay, qris, cstore (Indomaret / Alfamart), akulaku, and more. The response carries a `transaction_status` plus method-specific payment instructions (VA number, QR string, deeplink, or redirect URL). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ChargeRequest' responses: '200': description: Charge accepted (status may be pending, capture, or settlement). content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/status: parameters: - $ref: '#/components/parameters/OrderId' get: operationId: getTransactionStatus tags: - Core API summary: Get transaction status description: Retrieves the latest status of a transaction by order_id or transaction_id. responses: '200': description: The transaction status. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /v2/{order_id}/approve: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: approveTransaction tags: - Core API summary: Approve a challenged transaction description: Approves a card transaction that the fraud engine flagged with a challenge status. responses: '200': description: The transaction was approved. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/deny: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: denyTransaction tags: - Core API summary: Deny a challenged transaction description: Denies a card transaction that the fraud engine flagged with a challenge status. responses: '200': description: The transaction was denied. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/cancel: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: cancelTransaction tags: - Core API summary: Cancel a transaction description: Cancels a transaction before it settles. responses: '200': description: The transaction was cancelled. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/expire: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: expireTransaction tags: - Core API summary: Expire a pending transaction description: Immediately expires a pending transaction so it can no longer be paid. responses: '200': description: The transaction was expired. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/refund: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: refundTransaction tags: - Core API summary: Refund a transaction description: Refunds a settled transaction, fully or partially. requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/RefundRequest' responses: '200': description: The refund result. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' /v2/{order_id}/refund/online/direct: parameters: - $ref: '#/components/parameters/OrderId' post: operationId: directRefundTransaction tags: - Core API summary: Online direct refund description: Performs a direct (online) refund for supported payment channels (e.g. GoPay, QRIS, ShopeePay), returning funds without the standard refund settlement window. requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/RefundRequest' responses: '200': description: The direct refund result. content: application/json: schema: $ref: '#/components/schemas/TransactionStatus' '401': $ref: '#/components/responses/Unauthorized' components: responses: Unauthorized: description: Missing or invalid credentials. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: The requested resource was not found. content: application/json: schema: $ref: '#/components/schemas/Error' parameters: OrderId: name: order_id in: path required: true description: The merchant order_id (or Midtrans transaction_id) of the transaction. schema: type: string schemas: RefundRequest: type: object properties: refund_key: type: string description: Merchant-supplied unique key for this refund. amount: type: integer description: Amount to refund; omit for a full refund. reason: type: string Action: type: object properties: name: type: string method: type: string url: type: string format: uri TransactionDetails: type: object required: - order_id - gross_amount properties: order_id: type: string gross_amount: type: integer description: Total amount in the smallest currency unit (IDR has no decimals). ChargeRequest: type: object required: - payment_type - transaction_details properties: payment_type: type: string enum: - credit_card - bank_transfer - echannel - gopay - shopeepay - qris - cstore - akulaku - bca_klikpay - bca_klikbca - bri_epay - cimb_clicks - danamon_online transaction_details: $ref: '#/components/schemas/TransactionDetails' item_details: type: array items: $ref: '#/components/schemas/ItemDetail' customer_details: $ref: '#/components/schemas/CustomerDetails' bank_transfer: type: object properties: bank: type: string enum: - permata - bca - bni - bri - cimb credit_card: type: object properties: token_id: type: string authentication: type: boolean save_token_id: type: boolean gopay: type: object additionalProperties: true shopeepay: type: object additionalProperties: true CustomerDetails: type: object properties: first_name: type: string last_name: type: string email: type: string phone: type: string TransactionStatus: type: object properties: status_code: type: string status_message: type: string transaction_id: type: string order_id: type: string gross_amount: type: string payment_type: type: string transaction_time: type: string transaction_status: type: string enum: - authorize - capture - settlement - pending - deny - cancel - expire - refund - partial_refund - failure fraud_status: type: string enum: - accept - challenge - deny va_numbers: type: array items: type: object properties: bank: type: string va_number: type: string actions: type: array items: $ref: '#/components/schemas/Action' ItemDetail: type: object properties: id: type: string price: type: integer quantity: type: integer name: type: string Error: type: object properties: status_code: type: string status_message: type: string id: type: string securitySchemes: serverKeyAuth: type: http scheme: basic description: 'HTTP Basic authentication. Your Server Key is the username and the password is empty, so the header is `Authorization: Basic base64(SERVER_KEY:)`. Iris disbursement uses the same HTTP Basic scheme but with its own creator / approver API key.'