Direct API

PayLater

Akulaku, Kredivo and Indodana: the buyer pays in instalments, you are paid in full.

Private preview. PayLater is open to selected accounts only. Want it on yours? Email halo@kasera.id. Until it is enabled, a create naming one of these codes is refused 422 payment_method_unavailable.

The buyer leaves your page, signs in to the lender, picks a tenor and is approved there, then comes back to your return_url. You receive the full amount like any other payment; the instalments are between the buyer and the lender.

Integration steps

  1. Create the payment request.
  2. Send the buyer to payment.redirect_url.
  3. Acknowledge the payment — the payment.paid webhook.
  4. Check status when you need certainty: GET /v1/transactions/:id.

What each lender needs

Fieldakulakukredivoindodana
customer.name✓✓✓
customer.email✓✓✓
customer.phone✓✓✓
customer.address—✓✓
  • customer.phone must have 10 to 15 digits, country code included. 081234567890 and +6281234567890 both work.
  • customer.address is line, city and postal_code. It counts only when all three are there; half an address is treated as no address.
  • On Direct API a missing or unusable field is refused 422 customer_required, with the field named. On Checkout you may leave them out and the page asks the buyer.
{
  "error": {
    "code": "customer_required",
    "message": "...",
    "fields": { "customer.address": "required" }
  }
}

1. Create the payment request

order_items is optional. The lender shows the buyer what they are paying for, so send it when you have it; the items must add up to amount or the create is refused 422 order_items_mismatch. Left out, the lender sees one line with your description.

curl https://pay.kasera.id/v1/transactions \
  -H "Authorization: Bearer kp_live_..." \
  -H "Idempotency-Key: order-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1500000,
    "external_id": "ORD-1234",
    "payment_methods": ["kredivo"],
    "return_url": "https://toko.example/selesai",
    "customer": {
      "name": "Budi Santoso",
      "email": "budi@example.com",
      "phone": "081234567890",
      "address": {
        "line": "Jl. Sudirman No. 1",
        "city": "Kota Administrasi Jakarta Selatan",
        "postal_code": "12190"
      }
    },
    "order_items": [
      { "name": "Kursi kerja", "price": 1500000, "quantity": 1 }
    ]
  }'
{
  "id": "payreq_9b2f...",
  "status": "pending",
  "payment_method": "kredivo",
  "payment": {
    "type": "redirect",
    "redirect_url": "https://sandbox.kredivo.com/...",
    "display_name": "Kredivo"
  },
  "expires_at": "2026-10-01T13:00:00+07:00"
}

2. Send the buyer there

Navigate the browser to payment.redirect_url — not an iframe, not a popup. If the lender declines the buyer, the payment ends failed; create a new one so they can pay another way.

3. Acknowledge the payment

The buyer coming back to return_url is navigation, not proof — a buyer who gave up at the lender returns to the same URL. Fulfil on the payment.paid webhook, or retrieve the request server-side before you show anything final.

Refunds

Kasera Pay does not refund PayLater payments. Returns follow your own store policy, settled with the buyer directly.