Electricity topup (current)

Deprecated for new integrations

The Current API is deprecated for new integrations. It stays online indefinitely for backward compatibility — existing wiring doesn't need to change — but new builds should target v1 Purchases instead. The v1 endpoint also covers airtime and water, not just electricity.

Two-phase flow. Validate to pre-check the meter and quote charges, then confirm to actually generate tokens. Retry is for self-managed recovery from timeouts.

MethodPathIdempotent?
POST/api/topup/validateSafe — no state change
POST/api/topup/confirmNo — issues tokens / debits funds
POST/api/topup/retrySafe — looks up + reattempts a prior failure

Validate

POST /api/topup/validate
Authorization: Bearer <access_token>
curl
bash
curl -X POST https://api.scratchpower.com/api/topup/validate \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100,
    "beneficiary_phone_number": "26771436390",
    "charges_on_top_flag": false,
    "comment": "This is a comment.",
    "currency": "BWP",
    "date": "2024-06-18 04:10:59",
    "debited_account_id": 2,
    "external_reference": "00000001",
    "hard_validate": false,
    "language": "en-BW",
    "meter_number": "04040404040",
    "send_beneficiary_email": false,
    "send_beneficiary_sms": false,
    "send_requester_email": false,
    "send_requester_sms": false,
    "source_channel": "USSD",
    "source_tag": "SPWMM"
  }'

Request fields

FieldTypeRequiredNotes
source_channelstringyesWEB, SMART_APP, USSD, SMS_MO, BATCH
languagestringyesLocale tag (e.g. en-BW)
source_tagstringoptionalFree-form gateway/source identifier
debited_account_idintegeryesFrom /auth/me accounts[].id
beneficiary_phone_numberstringyesE.164 (e.g. 26771436390)
meter_numberstringyesThe electricity meter (typically 11 or 13 digits)
amountnumberyesAmount in currency units
currencystringyesISO 4217
charges_on_top_flagbooleanoptionaltrue (default): operator pays charges on top of amount. false: charges deducted from amount.
commentstringoptionalFree text
external_referencestringoptionalYour reference — used for retries
hard_validatebooleanoptionalWhen true, attempts to generate a dummy token; useful for end-to-end smoke tests
send_requester_* / send_beneficiary_*booleanoptionalNotification flags. Set all to false if you want to handle SMS/email yourself.

Response

200 OK (success)
json
{
  "id": 20,
  "channel": "USSD",
  "status": "ON_GOING",
  "type": "TOPUP",
  "operator": { "id": 6, "full_name": "ScratchPower Dealer", ... },
  "requester": { "id": 6, "full_name": "ScratchPower Dealer", ... },
  "payer": {},
  "beneficiary": {
    "id": 13,
    "full_name": "26771436390",
    "phone_number": "26771436390",
    "address": "",
    "status": "ACTIVE"
  },
  "total": "BWP 100.00",
  "net": "BWP 100.00",
  "charge": "BWP 0.00",
  "commission": "BWP 0.00",
  "entry": "BWP 100.00",
  "meter_number": "04040404040",
  "meter_details": "John Smith",
  "metadata": {}
}
200 OK (error during validation)
json
{
  "response_code": "810",
  "response_message": "Electricity recharge validation failed: 500 - Your meter number has been blocked and cannot purchase electricity. Please contact BPC.",
  "timestamp": 1718719194001,
  "developer_message": "com.tocchae.scratchPower.exception.TopupIntegrationServiceException",
  "errors": {}
}

meter_details is the verified consumer name returned by BPC. Surface it to the user before confirm so they can catch typos.

Confirm

http
POST /api/topup/confirm
Authorization: Bearer <access_token>

Same request body as /validate. Response includes the provider-issued token field. Single-token responses carry the bare token value (the provider's description, e.g. "Credit Token", is stripped server-side). Multi-token responses (auto-key-change, etc.) carry a |-separated list of Description: Token pairs with the descriptions preserved — detect the multi-token shape by checking whether token contains |. See Token format on the v1 reference page for the full parsing pattern; the wire format is identical between Current and v1.

200 OK (success — multi-token)
json
{
  "id": 26,
  "channel": "USSD",
  "status": "SUCCESSFUL",
  "type": "TOPUP",
  "reference": "TOP/2024/06/1871610006",
  "total": "BWP 1000.00",
  "net": "BWP 1000.00",
  "charge": "BWP 0.00",
  "commission": "BWP 0.00",
  "entry": "BWP 1000.00",
  "token": "KeyChange Token1: 8190 1047 0212 0545 2032|KeyChange Token2: 8190 1047 0112 0545 2032|Credit Token: 0404 0404 1980 0000 1917",
  "meter_number": "04040404198",
  "electricity_units": "191.7kWh",
  "meter_details": "Simon Sais",
  "metadata": {
    "vat": "BWP 245.62",
    "levy": "BWP 0.00",
    "regulatory_fee": "BWP 0.00",
    "charge": "BWP 1000.00",
    "cost": "BWP 754.38",
    "provider_meter_details": "SGC: 901047, TI: 2, KRN: 1",
    "provider_transaction_identifier": "52086"
  }
}
Confirm is not idempotent

Re-sending the same /confirm payload after a successful response issues a brand-new transaction. Always store the returned id / reference on success and avoid re-sending. For ambiguous timeouts use /api/topup/retry (below) — never just re-send confirm.

Retry

When confirm times out (network drop, provider slow), you don't know whether the transaction succeeded. /retry looks up your previous attempt by meter_number + external_reference, asks the provider whether it actually completed, and either returns the original token or surfaces the genuine failure.

http
POST /api/topup/retry
Authorization: Bearer <access_token>
curl
bash
curl -X POST https://api.scratchpower.com/api/topup/retry \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2024-06-18 04:10:59",
    "external_reference": "00000008",
    "language": "en-BW",
    "meter_number": "04040404040",
    "source_channel": "USSD",
    "source_tag": "SPWMM"
  }'

Response shape mirrors /confirm. A successful response means the original transaction completed — show the returned token to the user. A failure means the transaction genuinely failed; you can issue a fresh /confirm.

Notification flags

Every notification flag (send_requester_sms, send_beneficiary_sms, send_requester_email, send_beneficiary_email) can be set to false to suppress server-side SMS/email and let your integration deliver the messaging itself.

Failed transaction handling

Two options:

  • Automated managed retries — Scratch Power retries failed transactions in the background (up to 5 attempts over 30 minutes), notifies the customer via SMS, and refunds if all attempts fail.
  • Self-managed retries — use /api/topup/retry to verify the status with BPC before deciding to attempt another transaction.

Accounts default to self-managed. Email support@scratch-power.com to switch.