Legacy payment link

Bob Pay API documentation (legacy)

Generating a payment URL

This documentation describes the legacy method of generating payment URLs by manually constructing query parameters and signatures. For new integrations, we recommend using the modern Payment Intent API, which provides a more streamlined integration experience.

To direct your customer to the Bob Pay payment screen using the legacy method, you must construct a URL with query parameters and a security signature.

  • Sandbox environment: https://sandbox.bobpay.co.za/pay
  • Production environment: https://my.bobpay.co.za/pay

Required query parameters

Include the following query parameters in your payment URL. Replace the example values with your actual data. All parameter values must be URL-encoded.

Parameter Example Value Required Description
recipient_account_code SAN001 Yes Your unique Bob Pay account code.
custom_payment_id 478 Yes Your unique reference/identifier for this payment. This will be returned in notifications.
email [email protected] Conditional* Customer's email address.
mobile_number +27821234567 Conditional* Customer's mobile number in international format (e.g., +27821234567).
amount 499.99 Yes Payment amount in ZAR. Must be greater than zero.
item_name Order 1452 No Name of the product or service being purchased.
item_description Lego Star Wars No Detailed description of the product or service.
notify_url https://api-my-store.co.za/payment/bobpay Yes Webhook URL where payment status notifications will be sent.
success_url https://my-store.co.za/accounts/payment-confirmation Yes URL to redirect the customer after a successful payment.
pending_url https://my-store.co.za/accounts/payment-confirmation Yes URL to redirect the customer when the payment is pending.
cancel_url https://my-store.co.za/accounts/payment-cancel Yes URL to redirect the customer if they cancel the payment.
signature (generated using MD5 hash, see below) Yes Security signature to validate data integrity. This must be generated as described below.
payment_method instant-eft (optional) No Specific payment method to show the customer. Omit to show all available payment methods.

* Note: Either email or mobile_number must be provided.

Generating the signature

The signature parameter is a security measure to validate data integrity and prevent tampering. You must generate this signature using an MD5 hash of your payment parameters combined with your account passphrase.

Important notes:

  • The signature must be calculated from parameters in the exact order shown below
  • The payment_method parameter is NOT included in signature generation
  • Your account passphrase is a secret key that can be found in your Bob Pay merchant account settings

Signature generation steps

  1. Construct the parameter string by concatenating the following key-value pairs in this exact order, separated by &:

    recipient_account_code
    custom_payment_id
    email
    mobile_number
    amount
    item_name
    item_description
    notify_url
    success_url
    pending_url
    cancel_url
    
  2. URL-encode each value using form encoding, where spaces are encoded as + (this matches PHP's urlencode and Go's url.QueryEscape; with JavaScript's encodeURIComponent you must additionally replace %20 with +)

  3. Append your passphrase to the string: &passphrase=your_secret_passphrase

  4. Calculate the MD5 hash of the complete string to generate the signature

Example signature generation

Let's walk through a complete example:

Step 1: Construct the parameter string with URL-encoded values:

recipient_account_code=SAN001&custom_payment_id=478&email=customer%40bob.co.za&mobile_number=&amount=499.99&item_name=Order+1452&item_description=Lego+Star+Wars&notify_url=https%3A%2F%2Fapi-sandbox.bobpay.co.za%2Fpayment%2Fbobpay&success_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-confirmation%3Fprovider%3Dbobpay%26id%3D478&pending_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-confirmation%3Fprovider%3Dbobpay%26id%3D478&cancel_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-cancel%3Fprovider%3Dbobpay%26id%3D478

Step 2: Append the passphrase (example passphrase: your_secret_passphrase):

recipient_account_code=SAN001&custom_payment_id=478&email=customer%40bob.co.za&mobile_number=&amount=499.99&item_name=Order+1452&item_description=Lego+Star+Wars&notify_url=https%3A%2F%2Fapi-sandbox.bobpay.co.za%2Fpayment%2Fbobpay&success_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-confirmation%3Fprovider%3Dbobpay%26id%3D478&pending_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-confirmation%3Fprovider%3Dbobpay%26id%3D478&cancel_url=https%3A%2F%2Fsandbox.bobpay.co.za%2Faccounts%2Fpayment-cancel%3Fprovider%3Dbobpay%26id%3D478&passphrase=your_secret_passphrase

Step 3: Calculate the MD5 hash of the entire string:

Result: fb07364464def00311c85d306003ef3d

Step 4: Append this signature to your payment URL along with all the other parameters before redirecting the customer.

Complete integration example

Below is a complete Node.js example demonstrating how to generate a payment URL with a valid signature:

const crypto = require("crypto");

// URL-encode a value using form encoding (spaces become "+"),
// matching PHP's urlencode and Go's url.QueryEscape
function queryEscape(value) {
  return encodeURIComponent(value)
    .replace(/%20/g, "+")
    .replace(/[!'()*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
}

function generatePayURL(bobPayWebsiteURL, kvPairs, passphrase) {
  const signature = generateSignature(kvPairs, passphrase);
  const url = `${bobPayWebsiteURL}/pay?${kvPairs
    .map((kv) => `${kv.key}=${queryEscape(kv.value)}`)
    .join("&")}&signature=${signature}`;
  return url;
}

function generateSignature(kvPairs, passphrase) {
  const params = kvPairs
    .map((kv) => `${kv.key}=${queryEscape(kv.value)}`)
    .join("&");
  const stringToHash = `${params}&passphrase=${passphrase}`;
  return crypto.createHash("md5").update(stringToHash).digest("hex");
}

// Example usage
const kvPairs = [
  { key: "recipient_account_code", value: "SAN001" },
  { key: "custom_payment_id", value: "478" },
  { key: "email", value: "[email protected]" },
  { key: "mobile_number", value: "" },
  { key: "amount", value: "499.99" },
  { key: "item_name", value: "Order 1452" },
  { key: "item_description", value: "Lego Star Wars" },
  { key: "notify_url", value: "https://api-sandbox.bobpay.co.za/payment/bobpay" },
  {
    key: "success_url",
    value: "https://sandbox.bobpay.co.za/accounts/payment-confirmation?provider=bobpay&id=478",
  },
  {
    key: "pending_url",
    value: "https://sandbox.bobpay.co.za/accounts/payment-confirmation?provider=bobpay&id=478",
  },
  {
    key: "cancel_url",
    value: "https://sandbox.bobpay.co.za/accounts/payment-cancel?provider=bobpay&id=478",
  },
];

const bobPayPassphrase = "your_secret_passphrase"; // Replace with your actual passphrase
const bobPayWebsiteURL = "https://sandbox.bobpay.co.za";
const bobPayURL = generatePayURL(bobPayWebsiteURL, kvPairs, bobPayPassphrase);

console.log("Payment URL:", bobPayURL);
// Redirect your customer to this URL

Validating your signature

To verify that you've generated the signature correctly before going live, you can use the signature validation endpoint:

Endpoint: POST /payments/intents/signature

Base URLs:

  • Sandbox: https://api.sandbox.bobpay.co.za/v2/payments/intents/signature
  • Production: https://api.bobpay.co.za/v2/payments/intents/signature

Request body: Send the payment intent parameters including your generated signature

If your signature is valid, the endpoint will return a 200 OK response. If the signature is invalid, you'll receive a 400 Bad Request error.

Payment methods

By default, when a customer visits the payment URL, they are presented with all available payment methods enabled for your merchant account. However, you can direct customers to a specific payment method by adding the payment_method query parameter to the payment URL.

Available payment methods

Value Description
account-balance Pay using Bob Pay account balance
credit-card Credit or debit card payment (Visa, Mastercard, Amex, Diners)
apple-pay Apple Pay
google-pay Google Pay
instant-eft Real-time bank transfer via Instant EFT
manual-eft Upload proof of payment for manual EFT transfer
pay-shap PayShap instant payment method
capitec-pay Capitec Pay instant payment method
scan-to-pay Scan to Pay (QR code payment)
nedbank-direct-eft Nedbank Direct EFT instant payment method
absa-pay Absa Pay instant payment method

Handling notifications

When a payment is completed, Bob Pay sends a POST notification to the notify_url you specified. This webhook notification contains the complete payment details and requires proper security validation.

Security & validation requirements

To ensure the webhook is legitimate and the payment is valid, you must perform the following security checks:

1. Verify source IP address

All webhook requests originate from Bob Pay's static IP addresses. Verify that the request comes from one of these IPs:

  • Sandbox environment: 13.245.58.93
  • Production environment: 13.246.100.25

2. Validate the signature

The webhook payload includes a signature field. Verify this signature using the same MD5 hashing process described in the "Generating the Signature" section above. This confirms the data hasn't been tampered with.

Note: Use your own recipient_account_code value when recalculating the signature — the payload's top-level recipient_account_code field is always empty (your account code is also available in recipient_account.account_code).

3. Verify the amount

Ensure the paid_amount in the webhook matches the expected amount for your order. Note that some payment methods may allow non-exact payments if enabled for your account.

4. Validate with Bob Pay

After verifying the signature and amount, confirm the payment's validity with Bob Pay by calling the validation endpoint.

Endpoint: POST /payments/intents/validate

Base URLs:

  • Sandbox: https://api.sandbox.bobpay.co.za/v2/payments/intents/validate
  • Production: https://api.bobpay.co.za/v2/payments/intents/validate

Request body: Send the complete webhook payload you received.

Responding to webhooks

Critical: You must return a 200 OK HTTP status code to acknowledge receipt of the webhook. If Bob Pay doesn't receive a 200 OK response, it will retry sending the webhook with increasing delays, up to 17 retries over approximately 4 days.

Best practices:

  • Make your webhook endpoint idempotent (able to handle duplicate notifications safely)
  • Use the uuid or custom_payment_id to prevent processing the same payment multiple times
  • Store webhook receipts in your database to track which notifications you've already processed
  • Return 200 OK as quickly as possible; perform time-consuming operations asynchronously