Skip to content
StraventaDocs
Payment Methods

Virtual Account — Mandiri

Bank transfer via Mandiri VA — T+1 settlement, programmatic refunds

Virtual Accounts (Mandiri) issue a unique account number per intent. The payer transfers the exact amount from their banking app. Reliable for B2B / invoicing and any flow where the payer prefers a familiar bank-app UX.

FieldValue
allowed_channels valueva_mandiri
TTL24 h
Refund supportProgrammatic via POST /v1/payments/intents/{id}/attempts/{attemptId}/refunds
SettlementT+1
Channel-typed response fieldsva_number, va_bank, expires_at

Create intent

curl -X POST https://sandbox.505pay.link/v1/payments/intents \
  -H "Authorization: Bearer $PAYOPS_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $YOUR_KEY" \
  -d '{
    "merchant_id": "'"$PAYOPS_MERCHANT_ID"'",
    "amount_idr": 150000,
    "max_uses": 1,
    "allowed_channels": ["va_mandiri"]
  }'

The response includes va_number (the account number the payer transfers to) and expires_at. Display these to the payer with a copy-to-clipboard button.

Sandbox simulator

curl -X POST "https://sandbox.505pay.link/v1/payments/intents/$INTENT_ID/sandbox-complete" \
  -H "Authorization: Bearer $PAYOPS_SECRET_KEY"

Refunds

curl -X POST \
  "https://sandbox.505pay.link/v1/payments/intents/$INTENT_ID/attempts/$ATTEMPT_ID/refunds" \
  -H "Authorization: Bearer $PAYOPS_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: refund-$INTENT_ID-1" \
  -d '{"amount_idr": 150000, "reason": "customer_request"}'

See the refund recipe for the per-attempt flow.

Webhook events

  • payment_intent.created
  • payment.completed
  • payment_intent.expired
  • payment.refunded

See Payment lifecycle.

Was this page helpful?

On this page