moneybee
Home / Developers / Botim via MoneyBee

Botim via MoneyBee.
One integration, every Botim rail.

MoneyBee signs, encrypts and reconciles every Botim Money order for you. You send one payment intent; MoneyBee speaks Botim's API, handles 3-D Secure, confirms the result twice and posts it to your ledger.

What you can accept

RailPayer experienceToken prefix
Botim Pay walletThe Botim app opens, the payer confirms, returns to youbotim: (scene EWALLET)
Botim hosted pageBotim's own page with every method enabled on your MIDbotim: (scene PAYPAGE)
Cards on your form3-D Secure OTP page, then back to youbotimcard:
Hold now, capture laterSame as cards; capture or void within the hold windowbotimcard: with capture: false
Apple Pay, Google Pay, Samsung PayNative wallet sheet, usually frictionlessbotimdevice:
Subscriptions and instalmentsOne authenticated payment, then charges without the payerbotimcard: with an agreement, then botimmit:

Everything is AED. Botim is available to merchants onboarded on MoneyBee's UAE profile. Ask us to enable it on your MID.

How it works

You never talk to Botim directly. Every call below is a normal MoneyBee payment intent with connector_id: "botim" and a payment method token that tells MoneyBee which Botim rail to use. MoneyBee builds the Botim order, signs it with your merchant key, encrypts any card fields with Botim's public key, and maps Botim's statuses back to MoneyBee states.

curl -X POST https://api.moneybee.world/v1/payment_intents \
  -H "authorization: Bearer $MONEYBEE_KEY" \
  -H "idempotency-key: order-2041" \
  -H "content-type: application/json" \
  -d '{"amount": {"minor": 25000, "currency": "AED"}, "capture": true,
       "connector_id": "botim", "payment_method_token": "botim:eyJzY2VuZSI6IkVXQUxMRVQiLCJyZWRpcmVjdFVybCI6Imh0dHBzOi8vc2hvcC5leGFtcGxlL3JldHVybiJ9"}'

The response is a payment intent. When the payer still has something to do, its status is requires_action and Next actions tells you where to send them.

Payment method tokens

A token is a prefix, a colon, and a base64url-encoded JSON object. Build it on your server:

const token = (prefix, obj) => prefix + ':' + Buffer.from(JSON.stringify(obj)).toString('base64url');
PrefixFields
botimscene (EWALLET default, or PAYPAGE), redirectUrl, subject (max 12), osType (IOS or ANDROID), terminalType (WEB, WAP, APP), customerId, email
botimcardredirectUrl, card {number, holderName, cvv, expYear, expMonth} or enc (already encrypted), customerId, email, realIP, saveCard, threeDSecure (default true), agreement (see subscriptions)
botimdeviceredirectUrl, devicePayType (APPLE_PAY, GOOGLE_PAY, SAMSUNG_PAY), card {number (DPAN), expYear, expMonth, cryptogram} or enc, eci, cryptoFmt (default 3DSECURE), customerId
botimmitauthProtocolNo from the first payment, subject

MoneyBee appends ?Orderid=<reference> to your redirectUrl so you can match the return to the payment.

Botim Pay wallet

Create the intent with a botim: token and scene EWALLET. The next action is a deep_link. On a phone, send the payer to it and the Botim app opens; on desktop, show it as a QR code. The payer confirms in Botim and is returned to your redirectUrl. Poll the intent or wait for the webhook; MoneyBee has already confirmed the order with Botim by then.

Botim hosted page

Scene PAYPAGE returns a redirect next action: Botim's own checkout with every method enabled on your Botim profile. Use it for payers without the Botim app. If you prefer to keep the payer on your site, the same URL can be rendered with Botim's JavaScript SDK (PayBy.createIframe).

Cards on your form (Direct Pay)

If your systems are PCI DSS compliant for handling card data, send the card in a botimcard: token. MoneyBee encrypts the number, name and CVV with Botim's public key before anything leaves our server. Botim answers with a 3-D Secure step; the next action is type 3ds with a URL on MoneyBee that renders Botim's OTP page. Send the payer there. After the OTP, Botim redirects to your redirectUrl.

{
  "redirectUrl": "https://shop.example/return",
  "card": { "number": "5123450000000008", "holderName": "A Payer", "cvv": "100", "expYear": "31", "expMonth": "05" },
  "customerId": "cust_8812", "email": "payer@example.com", "realIP": "94.200.1.1", "saveCard": false
}

Already encrypting on your side? Pass enc with cardNo, holderName and cvv as Botim-encrypted Base64 instead of card.

Hold now, capture later

Send "capture": false with a card token. MoneyBee places a PREAUTH order. After 3-D Secure the intent is authorized. Then:

POST /v1/payment_intents/{id}/capture     # places Botim's CAPTURE order, intent becomes captured
POST /v1/payment_intents/{id}/void        # places PREAUTHVOID, the hold is released

Botim's authorisation code and RRN are kept on the payment for your reconciliation.

Apple Pay, Google Pay, Samsung Pay

Register with Apple, Google or Samsung and have the wallet enabled on your Botim profile. Decrypt the wallet token on your server, then send the device card (DPAN), expiry, cryptogram and ECI in a botimdevice: token. MoneyBee encrypts them for Botim and submits a DEVICE_PAY order. DPAN payments are normally approved without an OTP; a Google Pay FPAN may return a 3DS step like a card.

Subscriptions and instalments (CIT and MIT)

The first payment is customer-initiated: a botimcard: token with saveCard: true, a stable customerId and an agreement:

"agreement": {
  "agreementType": "RECURRING",          // or UNSCHEDULED, INSTALLMENT
  "numberOfPayments": 12, "amountVariability": "FIXED",
  "expiryDate": "2027-11-01", "paymentFrequency": "MONTHLY", "minimumDaysBetweenPayments": 28
}

Once that payment is captured, read it: the payment carries authProtocolNo. Store it against the customer. Every later charge is merchant-initiated with no payer present:

"payment_method_token": "botimmit:"

MIT charges settle synchronously: the intent comes back captured or failed in the same call.

Next actions

When an intent is requires_action, ask MoneyBee what to do:

GET https://api.moneybee.world/uae/intents/{id}/next
{ "type": "deep_link", "url": "https://botim.me/botim/payby/open-iap-cashdesk?ft=..." }   // open the Botim app
{ "type": "redirect",  "url": "https://checkout.payby.com/..." }                          // Botim's page
{ "type": "3ds",       "url": "https://api.moneybee.world/uae/3ds/{id}" }                 // OTP page, hosted by MoneyBee

Results and webhooks

Botim tells MoneyBee the outcome on your payer's return and, separately, by a signed notification that MoneyBee verifies with Botim's public key and retries are deduplicated. You see one of two events on your MoneyBee webhook: payment.captured or payment.failed, signed with mb-signature as described in the main docs. Decline codes are prefixed botim_ and carry Botim's fail code, for example botim_ORDER_EXPIRED.

Refunds and voids

Refunds go back to the original method, full or partial, for orders up to 180 days old:

POST /v1/payment_intents/{id}/refunds   {"amount": {"minor": 5000, "currency": "AED"}}

A hold that was never captured is released with a void, not a refund.

Testing

WhatUse
Botim Pay walletBotim UAT app (Android), accounts +971 56 000 0000 to 0009, OTP 123456, payment password 132580
Cards5123 4500 0000 0008, expiry 05/31, CVV 100, then choose Success, Pending or Failure on the 3DS page
Sandbox baseYour MoneyBee sandbox key routes to Botim UAT automatically

PCI and security

  • Wallet, hosted page and device-pay flows keep card data away from your systems. Only botimcard: requires you to handle card data, so use it only if you are PCI DSS compliant, or send fields you encrypted yourself.
  • MoneyBee signs every Botim request with SHA256withRSA and verifies every Botim response and notification. Encrypted card fields can only be read by Botim.
  • Card numbers, CVVs and cryptograms are never logged. Audit records keep brand, last four, auth code and RRN.

Questions or a MID to enable? pt@moneybee.world or WhatsApp +971 55 861 2001.