v3.8
Payment buttons

Accept payments with one script tag

Drop a MyroPay button into any page. It renders the button, shows a loading state, and sends the customer to checkout.myropay.com. Your server still creates the session.

Pay with MyroPay
One-off payments by card, wallet, USSD or NGN bank transfer.
Pay with MyroPay Escrow
Funds are held until the buyer confirms the order.
Subscribe with MyroPay
Recurring billing backed by subscription plans.
Preview

Live preview

These are the real buttons from the SDK. The demo sessions are placeholders and won't complete a checkout.

How it works

The button never holds a secret

  1. The customer clicks the button.
  2. It calls your createSession function, which calls your own backend.
  3. Your backend calls MyroPay with your secret key and returns the response unchanged.
  4. The button reads checkout_url and redirects.
  5. Checkout returns the customer to your success_url or cancel_url.
Never call sessions.php or subscriptions.php from browser JS. The sk_live_ key must stay on your server.
Always verify with GET /sessions.php?session_id=... on your server before fulfilling. The redirect alone is not proof of payment; the payment.success webhook is the authoritative signal.
No code needed

Create buttons from your dashboard

If you don't have a backend, create the button in the Business dashboard under Payment Buttons: choose Pay, Escrow or Subscribe, set the price, and copy the two lines of HTML it gives you.

<div data-myropay-button data-type="pay" data-button-id="btn_live_xxxxxxxxxxxxxxxxxxxx"></div>
<script src="https://checkout.myropay.com/buttons/mrp-button.js" async></script>

The price, currency, escrow terms and redirect URLs are saved on MyroPay, so visitors can't change them from the page. Buttons created with a test app (btn_test_) run on sandbox.myropay.com; live buttons run on checkout.myropay.com. Subscribe buttons ask the customer for their email before payment. Prefer your own server? The guides below still apply.

Quick start

One-off payment

Your page
<div id="myropay-button"></div>
<script src="https://checkout.myropay.com/buttons/mrp-button.js"></script>
<script>
  MyroPay.Button({
    type: 'pay',
    createSession: async () => {
      // calls YOUR backend, not MyroPay
      const res = await fetch('/api/create-myropay-session', { method: 'POST' });
      return res.json();          // forward MyroPay's response as-is
    }
  }).render('#myropay-button');
</script>
Your backend (PHP)
<?php
// api/create-myropay-session.php: the only place the secret key lives
$ctx = stream_context_create(['http' => [
  'method'  => 'POST',
  'header'  => "Content-Type: application/json\r\nX-API-Key: " . getenv('MYROPAY_SECRET_KEY') . "\r\n",
  'content' => json_encode([
    'amount'      => 5000,          // whole units: ₦5,000
    'currency'    => 'NGN',         // NGN, USD, GBP, EUR, GHS, KES, ZAR or CAD
    'description' => 'Order #1042',
    'success_url' => 'https://yourshop.com/thank-you',
    'cancel_url'  => 'https://yourshop.com/cart',
  ]),
]]);
header('Content-Type: application/json');
echo file_get_contents('https://checkout.myropay.com/api/sessions.php?action=create', false, $ctx);
Amounts are whole currency units, not kobo or cents. Use a sk_test_ key while building; test sessions never move real money.
Escrow

Escrow payment

Same pattern with type: 'escrow'. Your backend adds the escrow fields when it creates the session.

MyroPay.Button({
  type: 'escrow',
  createSession: async () => (await fetch('/api/create-myropay-escrow-session', { method: 'POST' })).json()
}).render('#myropay-escrow-button');
{
  "amount": 45000,
  "currency": "NGN",
  "description": "3 seater sofa",
  "escrow": true,
  "escrow_condition": "Buyer confirms delivery and inspects the item",
  "escrow_deadline_days": 7,
  "success_url": "https://yourshop.com/thank-you",
  "cancel_url": "https://yourshop.com/cart"
}
Escrow sessions require full card entry, and the buyer gets a guest escrow portal to release or dispute. Escrow fee is 1.5%.
Subscriptions

Subscription payment

Your backend calls POST /api/subscriptions.php?action=subscribe, which creates the subscription and its first invoice's checkout session in one call.

MyroPay.Button({
  type: 'subscribe',
  createSession: async () => (await fetch('/api/create-myropay-subscription', { method: 'POST' })).json()
  // { subscription, invoice: { checkout_url, ... } }
}).render('#myropay-subscribe-button');
Create the plan once with create-plan (needs the subscriptions:create scope), then send its plan_id and the customer's email on each click. Billing mode is invoice (default), wallet_auto or card_token. With wallet_auto the customer is sent to the returned checkout link to authorise automatic payments once with their PIN; every later cycle is charged without asking again (see Subscriptions in the API reference).
No backend

Static payment links

If you already have a reusable session id or checkout URL, skip createSession.

<div data-myropay-button data-type="pay" data-session-id="cs_live_xxxxxxxxxxxx"></div>
<script src="https://checkout.myropay.com/buttons/mrp-button.js"></script>
MyroPay.Button({ type: 'pay', sessionId: 'cs_live_xxxxxxxxxxxx' }).render('#btn');
MyroPay.Button({ type: 'pay', checkoutUrl: 'https://checkout.myropay.com/?session=cs_live_xxx' }).render('#btn');
Reference

Options and return shapes

OptionTypeDescription
typestringpay (default), escrow or subscribe
createSessionfunctionSync or async. Its return value is read for a checkout URL.
sessionIdstringUse instead of createSession when you have a session id.
checkoutUrlstringUse when you already have the full URL.
labelstringOverride the button text.
colorstringAccent color (hex). Defaults per type.
targetstring_self (default) or _blank
hideBadgebooleanHide the "Escrow protected" badge.
badgeLabelstringOverride the escrow badge text.
onBeforeRedirectfunction(url)Runs just before redirecting.
onErrorfunction(error)Runs if createSession fails or returns nothing usable.
What createSession can return
ShapeResult
"cs_live_xxx"Treated as a session id
{ checkout_url }Used directly (sessions.php create)
{ session_id }A checkout URL is built from it
{ session: { session_id } }Same, nested one level
{ invoice: { checkout_url } }Subscriptions subscribe response
Styling and security

The SDK injects its own scoped CSS (.mrp-btn) and inline SVG icons, so it needs no stylesheet or web font. Validate amount, currency and order on your server; never trust values sent from the client to your createSession route. For a modal or inline checkout with only a public key, see the Checkout SDK.