Migo BNPL Connector Documentation
Welcome to the Migo Buy Now, Pay Later integration guide. This documentation will help you integrate Migo BNPL into your e-commerce platform quickly and efficiently.
Easy Integration
Implement BNPL payment channel in your ecommerce platform with minimal code changes
Insight & Analytics
Monitor and take informed decision from insights about payments in your management dashboard
Safe & Secure
Payment channels and information sharing are secure and protected.
Powered by Agile Tech
Getting Started
Integration with Migo BNPL is straightforward and can be completed in three simple steps. Our payment gateway seamlessly integrates with your existing checkout flow.
Dashboard Setup
Obtain your checkout URL and merchant code
Setup Interface
Configure the payment window
Handle Webhooks
Receive payment confirmations
Powered by Agile Tech
Dashboard Setup
Before you can start accepting BNPL payments, you need to set up your merchant account through the Migo dashboard. This section will guide you through the complete setup process.
Getting Your Login Credentials
Your login credentials will be shared with you by a Migo administrator after contacting our sales team. These credentials grant admin user access to the setup and management pages of your account with Migo.
Note: Keep your login credentials secure and do not share them with unauthorized personnel. Only admin users should have access to the dashboard.
Sandbox Environment
By default, your account will be in sandbox environment. This allows you to test the integration without processing real payments.
To Go Live:
- Complete the setup process (steps below)
- Execute at least one successful payment test in sandbox
Setup Process
The dashboard setup involves two critical steps that must be completed before you can start accepting payments:
Settlement Bank Account Details
The admin user must provide bank account details for settlement. After a loan offer is accepted by a user and an order is fulfilled, settlement for that order will be made into your designated account.
Settlement Timeline:
All payments will be made directly to the settlement account the next business day after the transaction is complete (T+1).
⚠️ Important - Lump Sum Settlement:
The total settlement paid into the designated account is the total sum of all accepted orders from the previous business day as one lump sum payment, NOT individual payments for each order.
Required Bank Information:
- Bank Name
- Account Number
- Account Name
Webhook URL Configuration
To complete the setup on the dashboard, the admin user must provide a webhook URL for receiving notifications when a loan offer is accepted by a user.
Webhook Purpose:
The webhook notification is sent to inform you to proceed to fulfill the order for the customer. This is a critical step in the payment flow.
Webhook URL Requirements:
- Must be a publicly accessible HTTPS endpoint
- Should respond with a 200 status code upon successful receipt
- Must be able to handle POST requests
- Recommended to implement idempotency for duplicate notifications
Example Webhook URL:
https://your-domain.com/api/webhooks/migo-payment https://api.your-store.com/webhooks/bnpl-notification
✅ After Setup Completion
Once you have completed the dashboard setup with your settlement bank account and webhook URL, you will receive your:
- Checkout URL - The endpoint to initialize payments
- Merchant Code - Your unique identifier for transactions
These credentials will be displayed in your dashboard and can be used to integrate the payment interface into your platform.
Powered by Agile Tech
Payment Gateway Integration
This section explains how to integrate Migo BNPL into your e-commerce platform's checkout flow. After completing your dashboard setup, you'll be ready to add Migo as a payment option for your customers.
Prerequisites: Ensure you have completed the dashboard setup and received your checkout URL and merchant code.
Add Migo BNPL Payment Option
The first step is to add Migo BNPL as a payment option on your checkout page, alongside your existing payment methods (credit card, bank transfer, etc.).
Implementation Tips:
- Display Migo BNPL prominently as a payment method
- Include clear messaging about "Pay in Installments" or "Buy Now, Pay Later"
- Consider adding the Migo logo for brand recognition
- Show benefits like "No credit card required" or "Flexible payment plans"
Open Payment Window with Checkout URL
When a customer selects Migo BNPL as their payment method, you need to open a new window displaying the Migo checkout interface. This can be done in two ways:
Option 1: iFrame
Embed the checkout experience within your page using an iframe
Option 2: New Tab/Window
Open the checkout in a new browser tab or popup window
The new window should open the checkout URL provided from your dashboard, along with the required parameters to initiate the payment properly.
⚠️ Required Query Parameters:
These parameters are essential to ensure the BNPL payment will be initiated properly without missing required information.
code- Your merchant code from the dashboardemail- Customer's email addressamount- Order total amount (in Naira)orderId- Unique order reference from your platform
Optional Query Parameters:
Including these parameters can improve the customer experience by pre-filling information.
firstName- Customer's first namelastName- Customer's last name
Example Implementation:
// Example checkout URL with parameters
const checkoutUrl = 'https://yoursite.com/bnpl-checkout?' +
'code=12323-3232323-f3434-43&' +
'email=customer@example.com&' +
'amount=50000&' +
'orderId=TK11203030302&' +
'firstName=John&' +
'lastName=Doe';
// Open in iframe
<iframe
src={checkoutUrl}
width="100%"
height="600px"
frameborder="0"
/><!-- Add to your checkout page -->
<button onclick='openMigoBNPL()'>
Pay with Migo BNPL
</button>
<script>
function openMigoBNPL() {
const email = 'customer@example.com';
const amount = 50000;
const url = 'YOUR_CHECKOUT_URL?' +
'email=' + encodeURIComponent(email) +
'&amount=' + amount;
// Open in modal/iframe
window.open(url, 'migoCheckout',
'width=600,height=700');
}
</script>🚨 Error Handling:
If any required information is missing or the dashboard setup is not complete, an error message will be displayed informing you of the next step to take.
Customer Checkout Flow
Once the BNPL payment page is initiated successfully, here's what happens:
Customer Reviews Loan Offers: The customer will see their available loan offers based on their eligibility.
Customer Selects Payment Plan: They choose their preferred repayment plan from the available options.
Customer Accepts Loan Offer: After reviewing terms, the customer confirms, accepts the loan offer and pay the fees (if applicable).
Automatic Window Closure: The payment window or iframe automatically closes.
Return to Your Platform: The customer is returned to your e-commerce platform to continue their checkout process.
✅ Seamless Experience:
The entire process is designed to be smooth and user-friendly. Once the customer completes the BNPL payment process, they are automatically returned to your platform without any manual intervention required.
📬 What Happens Next?
After the customer accepts a loan offer:
- Webhook Notification: You will receive a webhook notification at the URL you configured in your dashboard
- Order Fulfillment: This notification signals that you should proceed to fulfill the customer's order
- Settlement: You'll receive payment in your settlement account the next business day (T+1)
Make sure your webhook endpoint is properly configured to handle these notifications automatically.
Powered by Agile Tech
Payment Confirmation & Order Fulfillment
This section explains the webhook notification process and how to confirm order fulfillment with Migo. Understanding this workflow is crucial for completing the payment integration.
Important: Ensure your webhook URL is properly configured in the merchant dashboard to receive notifications.
Receiving Webhook Notifications
After the customer has accepted a loan offer, paid the fees (if applicable), and the loan is approved, a webhook will be sent to your designated webhook URL configured in the dashboard.
✅ When Webhooks Are Sent:
Webhooks are ONLY sent when the order is ready to be fulfilled and the loan has been accepted. This means the customer has successfully completed the BNPL payment process.
❌ When Webhooks Are NOT Sent:
- Failed payment fee transactions
- Customer declines or fails to accept an offer
- Customer abandons the BNPL flow
- Insufficient eligibility or rejected applications
🔄 What Happens When You Receive the Webhook:
- The payment gateway iframe or window automatically closes
- The customer returns to your checkout page
- You can now proceed to fulfill the customer's order
Example Webhook Payload:
{
"_id": "68ff7ebd5ca87b974785edba",
"orderId": "R17615745886108X8UO",
"status": "success",
"items": [
{
"name": "Shopping list",
"quantity": 1,
"unitPrice": {
"$numberDecimal": "198500"
}
}
],
"total": {
"$numberDecimal": "198500"
},
"user": {
"_id": "68fccd6de44a",
"email": "user@email.ng",
"firstName": "John",
"lastName": "Doe",
"phone": "090987654321"
},
"createdAt": "2025-10-27T14:16:29.833Z",
"updatedAt": "2025-10-27T18:23:36.021Z",
}Webhook Handling Best Practices:
- Respond with HTTP 200 status code to acknowledge receipt
- Process webhooks asynchronously to avoid timeouts
- Implement idempotency to handle duplicate notifications
- Validate the webhook payload before processing
- Log all webhook events for debugging and audit purposes
Confirming Order Fulfillment
After you fulfill the customer's order and display an order confirmation page, you must call the Migo API to confirm that the order has been fulfilled.
⚠️ Why This Is Important:
Confirming fulfillment notifies Migo that the order has been successfully completed. This is crucial for reconciliation, settlement processing, and maintaining accurate transaction records.
API Endpoint Details:
https://migoapi.agiletech.ng/api/order/fulfilmentRequired Headers:
{
"x-api-key": "YOUR_API_KEY_FROM_DASHBOARD"
"x-api-secret": "YOUR_API_SECRET_FROM_DASHBOARD"
}Note: The API key is available in your merchant dashboard after completing setup.
Request Body:
{
"orderId": "TK11203030302",
"email": "customer@example.com"
}Required Parameters:
orderId- The unique order reference from your platform (same as sent in checkout URL)email- The customer's email address
Example Implementation:
// Example: Confirm order fulfillment after processing
async function confirmOrderFulfillment(orderId, email, apiKey apiSecret) {
try {
const response = await fetch('https://migoapi.agiletech.ng/api/order/fulfilment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey // API key from your dashboard
'x-api-secret': apiSecret // API key from your dashboard
},
body: JSON.stringify({
orderId: orderId,
email: email
})
});
if (response.ok) {
console.log('Order fulfillment confirmed with Migo');
return true;
} else {
console.error('Failed to confirm fulfillment:', await response.text());
return false;
}
} catch (error) {
console.error('Error confirming fulfillment:', error);
return false;
}
}
// Call after showing order confirmation to customer
const API_KEY = 'your-api-key-from-dashboard';
confirmOrderFulfillment('TK11203030302', 'customer@example.com', API_KEY);📌 When to Call This API:
- After receiving the webhook notification
- After successfully processing the order in your system
- When displaying the order confirmation page to the customer
🔄 Complete Workflow Summary
Customer completes BNPL payment: Accepts loan offer and pays fees
Receive webhook notification: Migo sends webhook to your configured URL
Payment window closes: Customer returns to your platform
Process and fulfill order: Complete the order in your system
Confirm fulfillment: Call the API to notify Migo
Receive settlement: Payment deposited to your account (T+1)
Powered by Agile Tech
Webhook Signature Verification
Webhook signatures are used to ensure the integrity and authenticity of the data received through webhooks. This security measure helps you verify that webhook requests are genuinely from Migo and have not been tampered with.
Security Best Practice: Always verify webhook signatures to protect your system from malicious requests.
Why Verify Webhook Signatures?
Webhook signature verification provides critical security benefits:
Security Benefits:
- Authentication: Confirms the webhook is genuinely from Migo
- Data Integrity: Ensures the payload has not been modified in transit
- Protection: Guards against malicious actors attempting to send fake webhooks
- Compliance: Helps meet security and audit requirements
⚠️ Warning:
Without signature verification, your webhook endpoint is vulnerable to unauthorized requests that could trigger false order fulfillments.
How to Generate a Signature
Note: You don't need to generate signatures when sending requests to Migo. This section explains how Migo generates the signature that you'll receive in webhook requests, so you can verify them.
To verify a webhook signature from Migo, you need to understand how we generate it:
Get the Webhook Payload: Migo receives the complete webhook request body as a JSON object.
payload = { orderId: "123", status: "success", ... }Stringify the Payload : The payload is converted to a JSON string.
payloadString = JSON.stringify(payload)Generate HMAC-SHA256 Signature: Migo creates an HMAC-SHA256 hash using your merchantCode as the secret key and the stringified payload as the message.
signature = HMAC-SHA256(merchantCode, payloadString)Example: Generating Signature (Node.js)
const crypto = require('crypto');
function generateWebhookSignature(merchantCode, webhookPayload) {
// Step 1 & 2: Stringify the webhook payload
const payloadString = JSON.stringify(webhookPayload);
// Step 3: Generate HMAC-SHA256 signature
const signature = crypto
.createHmac('sha256', merchantCode)
.update(payloadString)
.digest('hex');
return signature;
}
// Example: How Migo generates the signature
const merchantCode = 'your-merchant-code';
const webhookPayload = {
orderId: 'ORD-123456',
status: 'success',
total: 18975,
// ... other order data
};
const signature = generateWebhookSignature(merchantCode, webhookPayload);
console.log('Generated Signature:', signature);
// This signature is sent in the x-webhook-signature header
Example: Generating Signature (Python)
import hashlib
import hmac
import json
def generate_webhook_signature(merchant_code, webhook_payload):
# Step 1 & 2: Stringify the webhook payload
payload_string = json.dumps(webhook_payload, separators=(',', ':'))
# Step 3: Generate HMAC-SHA256 signature
signature = hmac.new(
merchant_code.encode(),
payload_string.encode(),
hashlib.sha256
).hexdigest()
return signature
# Example: How Migo generates the signature
merchant_code = 'your-merchant-code'
webhook_payload = {
'orderId': 'ORD-123456',
'status': 'success',
'total': 18975,
# ... other order data
}
signature = generate_webhook_signature(merchant_code, webhook_payload)
print(f'Generated Signature: {signature}')
# This signature is sent in the x-webhook-signature header
How to Validate a Signature
When you receive a webhook request, validate the signature to ensure authenticity:
Retrieve Data: Get the payload and signature from the HTTP headers of the incoming webhook request
receivedSignature = request.headers['x-webhook-signature']Generate Local Signature: Use the same process described above to generate a signature from your API credentials
localSignature = HMAC-SHA256(merchantCode, rawRequestBody)Compare Signatures: Compare the locally generated signature with the received signature
if (localSignature === receivedSignature) { // Valid webhook }Result: If signatures match, the webhook data is valid and authentic
Example: Validating Webhook (Node.js/Express)
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/webhook/migo', express.raw({ type: 'application/json' }), (req, res) => {
try {
// Step 1: Retrieve signature from headers
const receivedSignature = req.headers['x-webhook-signature'];
if (!receivedSignature) {
return res.status(401).json({ error: 'Missing signature' });
}
// Step 2: Generate local signature using HMAC-SHA256
const merchantCode = process.env.MIGO_MERCHANT_CODE;
// IMPORTANT: Use raw body buffer, not parsed JSON
const rawBody = req.body.toString('utf8');
const localSignature = crypto
.createHmac('sha256', merchantCode)
.update(rawBody)
.digest('hex');
// Step 3: Compare signatures (use timing-safe comparison)
if (!crypto.timingSafeEqual(Buffer.from(localSignature), Buffer.from(receivedSignature))) {
console.error('Invalid signature');
return res.status(401).json({ error: 'Invalid signature' });
}
// Step 4: Signature is valid - parse and process webhook
const payload = JSON.parse(rawBody);
console.log('Valid webhook received:', payload);
// Process the order fulfillment
// ... your order processing logic here
// Return success
res.status(200).json({ success: true });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
Example: Validating Webhook (Python/Flask)
import hashlib
import hmac
from flask import Flask, request, jsonify
import os
app = Flask(__name__)
@app.route('/webhook/migo', methods=['POST'])
def migo_webhook():
try:
# Step 1: Retrieve signature from headers
received_signature = request.headers.get('x-webhook-signature')
if not received_signature:
return jsonify({'error': 'Missing signature'}), 401
# Step 2: Generate local signature using HMAC-SHA256
merchant_code = os.environ.get('MIGO_MERCHANT_CODE')
# IMPORTANT: Use raw request data, not parsed JSON
raw_body = request.get_data(as_text=True)
local_signature = hmac.new(
merchant_code.encode(),
raw_body.encode(),
hashlib.sha256
).hexdigest()
# Step 3: Compare signatures (use timing-safe comparison)
if not hmac.compare_digest(local_signature, received_signature):
print('Invalid signature')
return jsonify({'error': 'Invalid signature'}), 401
# Step 4: Signature is valid - parse and process webhook
payload = request.get_json()
print(f'Valid webhook received: {payload}')
# Process the order fulfillment
# ... your order processing logic here
# Return success
return jsonify({'success': True}), 200
except Exception as e:
print(f'Webhook processing error: {e}')
return jsonify({'error': 'Internal server error'}), 500
🔐 Security Best Practices
✓ Always Verify Signatures
Never process webhook data without first verifying the signature
✓ Use Environment Variables
Store API keys and merchant codes securely in environment variables, never hardcode them
✓ Log Validation Failures
Keep records of failed signature validations for security monitoring
✓ Use HTTPS Only
Ensure your webhook endpoint uses HTTPS to protect data in transit
✓ Return Appropriate Status Codes
Return 401 for invalid signatures and 200 for successful processing
Powered by Agile Tech
Understanding BNPL Fees
This section explains the underwriting fees that customers may need to pay when accepting a BNPL loan offer. Understanding the fee structure is important for setting proper customer expectations.
Important: Fees are determined by the loan underwriting process and must be paid before the loan offer can be accepted.
What Are Underwriting Fees?
When a customer initiates the BNPL payment gateway, they will be presented with loan offers for their purchase. To accept an offer, there is an underwriting fee that the customer is required to pay upfront.
⚠️ Critical Information:
The underwriting fee must be paid before the customer can accept a loan offer.
- No fee payment = No offer acceptance
- No offer acceptance = No order fulfillment notification
Key Points About Underwriting Fees:
- Fees are determined during the loan underwriting process
- The fee amount varies based on the loan offer and customer eligibility
- Fees are paid directly by the customer through the BNPL interface
- Payment must be completed before the loan offer is finalized
When Are Fees Charged?
Fees are presented to the customer during the BNPL checkout flow, after they review their loan offers and before they can accept one.
Customer Views Offers: Customer sees available loan offers with payment plans and terms.
Fee Presented: Underwriting fee is displayed before the customer can proceed.
Customer Pays Fee: Customer completes the fee payment transaction.
Offer Acceptance Enabled: Only after successful fee payment can the customer accept the loan offer.
Webhook Sent: After offer acceptance, webhook notification is sent to merchant for order fulfillment.
✅ Successful Flow:
Fee Payment → Offer Acceptance → Webhook Notification → Order Fulfillment
What This Means for Merchants
As a merchant, you don't need to handle fee collection or processing. However, understanding the fee structure helps you provide better customer support.
💡 Important to Remember:
- You will only receive webhook notifications after the fee has been paid and the offer accepted
- Failed fee payments do not trigger webhooks or order fulfillment
- Customers who cannot or do not pay the fee will not complete the BNPL checkout
❌ No Webhook Will Be Sent If:
- Customer fails to pay the underwriting fee
- Fee payment is declined or unsuccessful
- Customer abandons the checkout before paying the fee
- Customer declines to accept the offer after seeing the fee
Customer Support Tips:
- Inform customers that fees are determined by Migo's underwriting process
- Advise customers to complete the entire BNPL checkout flow including fee payment
- Let customers know they must pay the fee to proceed with the BNPL option
- Direct fee-related questions to Migo support: migo@agiletech.ng
Powered by Agile Tech
Need Help?
Our support team is here to help you get started with Migo BNPL integration. Whether you have questions about implementation, troubleshooting, or best practices, we're just an email away.
Contact Support: migo@agiletech.ng