Accept PaymentsInline Checkout

SaySwitch Inline Checkout

Inline Checkout lets you start a payment directly from your frontend website or frontend-only app using only your SaySwitch public key. It works for normal websites built with HTML, CSS, and JavaScript, and also works in frontend frameworks such as React, Vue, Angular, Svelte, and similar tools. It does not require a backend server to initialize the payment.

Never add your secret key to frontend code. Your secret key should not be placed in HTML files, JavaScript files, browser storage, or any code that runs in a customer’s browser.

When to Use Inline Checkout

Use Inline Checkout when:

  • You are building with plain HTML, CSS, and JavaScript
  • You are building with a frontend framework such as React, Vue, Angular, or Svelte
  • You do not have a backend server for payment initialization
  • You want customers to click a button and complete payment on the SaySwitch checkout page

Endpoint

POST https://backendapi.sayswitchgroup.com/api/inline/public/transaction/initialize

Authentication

Inline Checkout uses your public key only. You can send the public key in either of these ways:

  • In the request body as public_key
  • In the request header as x-pub-key

Do not use your secret key for Inline Checkout requests from a browser.

Required Payload

{
  "public_key": "pk_live_xxx",
  "reference": "unique_transaction_reference",
  "amount": "100.00",
  "currency": "NGN",
  "email": "customer@example.com",
  "name": "Customer Name",
  "callback_url": "https://your-domain.com/payment/callback"
}
ParameterTypeRequiredDescription
public_keystringYes, unless sent as x-pub-keyYour SaySwitch public key
referencestringYesYour unique payment reference
amountstringYesAmount to charge, for example "100.00"
currencystringYesPayment currency, for example NGN
emailstringYesCustomer’s email address
namestringYesCustomer’s name
callback_urlstringYesURL to redirect the customer to after checkout

Use callback_url as the callback field name. Do not use callback, redirect_url, or other aliases unless SaySwitch has explicitly confirmed support for them.

Optional Payload

{
  "phone": "2348012345678",
  "payment_options": ["card", "bank_transfer", "momo"]
}
ParameterTypeDescription
phonestringCustomer’s phone number
payment_optionsarrayPayment methods to show for this checkout

Full Native JavaScript Example

Add this to your checkout page. When the customer clicks Pay Now, your website or frontend app creates a payment session and redirects the customer to SaySwitch checkout.

A SaySwitch CDN helper for Inline Checkout is coming soon. For now, use the native JavaScript fetch method shown below.

<script>
async function startPayment() {
  const reference = 'SSW_DEMO_' + Date.now();
 
  const response = await fetch('https://backendapi.sayswitchgroup.com/api/inline/public/transaction/initialize', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      public_key: 'pk_live_xxx',
      reference: reference,
      amount: '100.00',
      currency: 'NGN',
      email: 'customer@example.com',
      name: 'Customer Name',
      callback_url: 'https://your-domain.com/payment/callback',
      payment_options: ['card', 'bank_transfer']
    })
  });
 
  const result = await response.json();
 
  if (!result.success) {
    alert(result.message || 'Payment could not be initialized');
    return;
  }
 
  window.location.href = result.data.authorization_url;
}
</script>
 
<button onclick="startPayment()">Pay Now</button>

Replace the sample values with your own values before going live:

Sample valueReplace with
pk_live_xxxYour SaySwitch public key
customer@example.comThe customer’s email address
Customer NameThe customer’s name
"100.00"The amount you want to charge, sent as a string
SSW_DEMO_ + Date.now()Your unique order or payment reference
https://your-domain.com/payment/callbackYour own callback page URL

If the customer enters details on your page, you can bind the values from your form fields. Convert the amount to a formatted string before sending it.

<input id="customerName" type="text" placeholder="Customer name" />
<input id="customerEmail" type="email" placeholder="Customer email" />
<input id="paymentAmount" type="number" step="0.01" placeholder="Amount" />
<button onclick="startPayment()">Pay Now</button>
 
<script>
async function startPayment() {
  const name = document.getElementById('customerName').value;
  const email = document.getElementById('customerEmail').value;
  const amount = Number(document.getElementById('paymentAmount').value).toFixed(2);
  const reference = 'SSW_DEMO_' + Date.now();
 
  const response = await fetch('https://backendapi.sayswitchgroup.com/api/inline/public/transaction/initialize', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      public_key: 'pk_live_xxx',
      reference: reference,
      amount: amount,
      currency: 'NGN',
      email: email,
      name: name,
      callback_url: 'https://your-domain.com/payment/callback'
    })
  });
 
  const result = await response.json();
 
  if (!result.success) {
    alert(result.message || 'Payment could not be initialized');
    return;
  }
 
  window.location.href = result.data.authorization_url;
}
</script>

You can also send your public key as a request header:

headers: {
  'Content-Type': 'application/json',
  'x-pub-key': 'pk_live_xxx'
}

Success Response

{
  "success": true,
  "message": "Authorization URL created",
  "data": {
    "authorization_url": "https://checkout.sayswitchgroup.com/pay/SSW_DEMO_1789394233792",
    "access_code": "ACCESS_CODE",
    "reference": "SSW_DEMO_1789394233792",
    "payment_options": ["card", "bank_transfer"]
  }
}

Redirect the customer to data.authorization_url to continue payment on the SaySwitch checkout page. The checkout URL uses this format:

https://checkout.sayswitchgroup.com/pay/{reference}

Validation Errors

If the request is incomplete or uses the wrong data type, SaySwitch returns a failed response with validation details.

Missing Reference

{
  "success": false,
  "message": "Incomplete request",
  "error": {
    "reference": ["The reference field is required."]
  }
}

Amount Sent as a Number

Send amount as a string, for example "100.00". Numeric values are rejected.

{
  "success": false,
  "message": "Incomplete request",
  "error": {
    "amount": ["The amount must be a string."]
  }
}

Invalid Public Key

{
  "success": false,
  "message": "Invalid public key"
}

Duplicate Reference

{
  "success": false,
  "message": "Transaction reference already exists"
}

Unsupported Currency

{
  "success": false,
  "message": "Unsupported currency"
}

Invalid Callback URL

{
  "success": false,
  "message": "The callback URL must be a valid http or https URL"
}

Handling the Callback Redirect

After payment, SaySwitch redirects the customer back to the callback_url you supplied during initialization. The redirect can include query parameters such as:

?reference=REFERENCE&status=success

Use the callback query parameters to identify the payment and show the customer that payment processing has returned to your website.

<!DOCTYPE html>
<html>
<head>
  <title>Payment Status</title>
</head>
<body>
  <h2>Checking payment status...</h2>
  <p id="status"></p>
 
  <script>
    const params = new URLSearchParams(window.location.search);
    const reference = params.get('reference');
    const status = params.get('status');
 
    const statusBox = document.getElementById('status');
 
    if (reference) {
      statusBox.innerText = 'Payment returned with status: ' + status + '. Reference: ' + reference;
    } else {
      statusBox.innerText = 'Payment returned. Please confirm your transaction status.';
    }
  </script>
</body>
</html>

The exact callback query parameters depend on the checkout response. Always use the reference to identify the payment.

Verify the Transaction

Do not rely only on the callback query parameters for final confirmation. After receiving the callback, verify the transaction by reference before showing final success or failure to the customer.

Use the Get Transaction by Reference documentation to confirm the transaction status with the reference returned from Inline Checkout.

The verification endpoint uses your secret key, so do not call it directly from frontend code. If you have a backend, verify the transaction from your backend. If you are running a frontend-only setup, confirm the transaction from your SaySwitch dashboard before fulfilling the order.

Important Notes

  • Always use a unique reference for every payment.
  • Send amount as a string, for example "100.00".
  • Use your test public key for test payments and your live public key for live payments.
  • Do not expose secret keys in frontend code.
  • Use callback_url as the callback field name.
  • The callback URL must be a valid http or https URL.
  • Verify the transaction by reference before fulfilling the order.

Payment Flow

  1. Customer clicks Pay Now on your website.
  2. Your frontend calls the Inline Checkout initialize endpoint with a unique reference.
  3. SaySwitch returns data.authorization_url.
  4. Customer is redirected to https://checkout.sayswitchgroup.com/pay/{reference}.
  5. Customer completes payment.
  6. SaySwitch redirects the customer back to your callback_url with query parameters such as reference and status.
  7. You verify the transaction by reference.
  8. After verification, you show the final payment status to the customer and fulfill the order if payment was successful.