Junipay API
    • JuniPay API Documentation
    • Authentication
      • Get Token for Payment Form (Unique Token + Secret)
        GET
    • Collections
      • Initiate Collection Payment
        POST
    • Disbursements
      • Transfer Funds
        POST
    • Remittance
      • Send Remittance
        POST
    • Transaction Status
      • Check Transaction Status
        GET
    • Verify Recipient
      • Verify Recipient
        GET
    • Webhooks
      • Webhook/Callback
        POST

    JuniPay API Documentation

    Base URL (Production): https://api.junipayments.com
    Content-Type: application/json
    Authentication: Bearer Token (JWT)

    1. Authentication#

    All API requests require authentication. There are two methods, depending on your integration:

    1.1 Payment Form / Payment Links#

    Use Case: Quick integration for merchants embedding JuniPay forms or sharing payment links.
    How: Request a token from your Token Link using your Client ID and Secret.
    Example (cURL):
    Response:
    {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...",
      "expires_in": 3600
    }

    1.2 Direct API Access (Collections, Disbursements, Remittance)#

    Use Case: Aggregators, advanced integrations, payouts.
    How: Generate JWT tokens using your private key with the RS256 algorithm.
    Examples in polular frameworks and languages:
    Node.js
    PHP
    Python
    Usage in requests:

    2. Error Handling#

    JuniPay follows standard HTTP status codes.
    CodeDescription
    200Request successful (check response payload for transaction status).
    201Resource created (e.g., payment or transfer).
    400Bad request (validation error, missing parameter).
    401Unauthorized (invalid or missing token).
    404Resource not found.
    500–504Server error (contact JuniPay support if persistent).
    Error Response Example:
    {
      "status": "error",
      "code": "INVALID_TOKEN",
      "message": "The token provided is expired or invalid."
    }

    3. Collections (Receiving Money)#

    3.1 Payment Links#

    Quickest way to start receiving payments.
    Generate links in your Dashboard.
    Share via social media, website, or directly.
    Example:
    https://junipayments.com/{your-business-name}

    3.2 Payment Form#

    Embed JuniPay’s hosted form directly into your website.
    Requires: clientId, secret, and a generated token.
    Integration Steps:
    Parameters
    ParameterTypeDescription
    keyStringToken generated using your secret key
    clientidStringYour client ID
    emailStringEmail address of customer
    amountDoubleAmount debiting customer.
    colorStringBackground color of payment form.
    descStringDescription of item/service being paid for.
    total_amntDoubleTotal amount to be paid (for multiple products).
    customer_tokenStringID of customer who has made payment before
    onCloseCallbackJavascript function that is called if the customer closes the payment window instead of making a payment.
    foreignIDStringOptional, Unique string that will be used to query a specific transaction
    callbackUrlStringURL the callback request will be sent to. Must be of method POST
    redirectUrlStringThe url payers will be redirected to after payment is made

    3.3 Collections API#

    Endpoint: POST /payment
    Request Example:
    Response Example:
    {
      "status": "pending",
      "message": "TRANSACTION PENDING",
      "transID": "COL1000001221896",
      "foreignID": "1754305435932",
      "reqToken": "1754305435932",
      "transactionId": "TX1234567890",
    
    }

    Header Parameters#

    These parameters are typically sent in the HTTP request header to authenticate your request.
    ParameterTypeDescription
    AuthorizationStringSet value to Bearer TOKEN
    clientidStringYour Client ID found on your Dashboard
    Content-TypeStringSet value to application/json

    Body Parameters#

    These parameters represent the data payload sent in your API request.
    ParameterTypeDescription
    channelStringPayment method: mobile_money or card
    phoneNumberStringCustomer's phone number (Required for mobile_money)
    providerStringCustomer's network provider (Required for mobile_money)
    amountDoubleAmount to transfer in Cedis
    tot_amntDoubleTotal amount to transfer in Cedis
    senderEmailStringPayer's email; used for sending transaction receipts
    descriptionStringDescription of the transaction
    foreignIDStringUnique string used to query a specific transaction later
    callbackUrlStringURL for the POST callback request after processing

    Note on Currency:#

    Both amount and tot_amnt are explicitly expected in Cedis (GHS). Ensure your backend logic calculates these values correctly before sending the request to avoid processing errors.

    4. Disbursements (Sending Money)#

    Prerequisites#

    Before using the Disbursement API, ensure you have completed the following steps:
    Compliance Verification: You must be verified by going through compliance and getting approved.
    API Access: You must request and be approved to use the Direct Access APIs.
    Key Generation: You need your private and public keys, which must be generated on the Getting Started page of your Dashboard.
    Token Generation Package: A package to generate your token from your private key (e.g., jsonwebtoken).

    Disbursement API Overview#

    The Disbursement API allows you to easily send money to Bank accounts or Mobile Money within your integration.

    1. Verify First#

    You are strongly advised to run the verify (resolve) endpoint to ensure the validity of the phone number or bank account number before creating the transfer recipients.

    2. Authentication & Authorization#

    Tokens are required to be generated and defined in the headers parameter for each request to be authorized.
    Tokens are generated from your private keys and are defined in the request parameters.
    Example: You can generate a token from a private key using the jsonwebtoken npm package in NodeJS.

    4.1 Verify Recipient#

    Endpoint: GET /resolve
    Purpose: Verify account/phone before sending.
    Here is the updated Markdown, maintaining your established formatting style. Note that since the second set of parameters are query parameters rather than body parameters, I have updated the section header to URL Query Parameters to accurately reflect your raw text.

    Header Parameters#

    These parameters are typically sent in the HTTP request header to authenticate your request.
    ParameterTypeDescription
    AuthorizationStringSet value to Bearer TOKEN
    clientidStringYour Client ID found on your Dashboard

    URL Query Parameters#

    These parameters are appended to the end of the URL path to filter or specify the request.
    ParameterTypeDescription
    channelStringChannel to be verified: mobile_money or bank
    phoneNumberStringPhone number to be verified (Required for mobile_money channel)
    providerStringNetwork provider of the phone number to be verified: mtn, vodafone, or airteltigo (Required for mobile_money channel)
    account_numberStringCustomer's bank account number (Required for bank channel)
    bank_codeStringCustomer's bank code (Required for bank channel)
    Request Example:

    4.2 Transfer Funds#

    Endpoint: POST /transfer
    Request Example:

    Header Parameters#

    These parameters are typically sent in the HTTP request header to authenticate your request.
    ParameterTypeDescription
    AuthorizationStringSet value to Bearer TOKEN
    clientidStringYour Client ID found on your Dashboard
    Content-TypeStringSet value to application/json

    Body Parameters#

    These parameters represent the data payload sent in your API request.
    ParameterTypeDescription
    channelStringChannel to transfer money to: mobile_money or bank
    phoneNumberStringCustomer's phone number (Required for mobile_money channel)
    providerStringCustomer's phone network provider (Required for mobile_money channel)
    account_numberStringCustomer account number (Required for bank channel)
    bank_codeStringCustomer's bank code (Required for bank channel)
    receiver_phoneStringRecipients phone number
    amountDoubleAmount to transfer in Cedis
    senderStringName of the sender
    receiverStringName of the receiver
    narrationStringThe reason for the transfer
    foreignIDStringUnique string that will be used to query a specific transaction
    callbackUrlStringURL the callback request will be sent to. Must be of method POST

    5. Remittance (Cross-Border Transfers)#

    5.1 Send Remittance#

    Endpoint: POST /sendremittance
    Request Example:

    6. Transaction Status#

    Endpoint:
    Collections: /checktranstatus
    Remittance: /checkremittancestatus
    Request Example:
    Response Example:
    {
      "status": "success",
      "transactionId": "TX1234567890",
      "transactionStatus": "completed",
      "amount": 150,
      "currency": "GHS"
    }

    Perfect — thanks for sharing your current docs and the sample callback response.
    Here’s the cleanest way to include callbacks in your JuniPay documentation:

    7. Webhooks & Callbacks#

    When a transaction is processed, JuniPay sends a server-to-server callback (webhook) to the callbackUrl you provided in your API request.
    Callbacks are sent for all transaction states:
    success → Payment or transfer completed.
    failed → Payment or transfer could not be processed.
    pending → Transaction still processing (e.g., awaiting customer approval).

    7.1 Webhook Request#

    Method: POST
    Headers:
    Sample Payload (Success):
    {
      "status": "success",
      "message": null,
      "trans_id": "COL100001221903",
      "foreignID": "1754305527617",
      "date": "2025-08-04 11:05:28",
      "amount": 1,
      "channel": "mobile_money",
      "provider": "mtn",
      "phoneNumber": "0557079838"
    }
    Sample Payload (Failed):
    {
      "status": "failed",
      "message": "Insufficient funds",
      "trans_id": "COL100001221904",
      "foreignID": "1754305527618",
      "date": "2025-08-04 11:10:15",
      "amount": 1,
      "channel": "mobile_money",
      "provider": "mtn",
      "phoneNumber": "0557079838"
    }
    Sample Payload (Pending):
    {
      "status": "pending",
      "message": "Awaiting customer approval",
      "trans_id": "COL100001221905",
      "foreignID": "1754305527619",
      "date": "2025-08-04 11:15:40",
      "amount": 1,
      "channel": "mobile_money",
      "provider": "mtn",
      "phoneNumber": "0557079838"
    }

    7.2 Response from Your Server#

    Your server must respond with HTTP 200 OK to confirm receipt:
    If no 200 response is returned, JuniPay will retry the callback multiple times.

    8. Bank Codes#

    CodeBank Name
    2001Access Bank
    2002Absa Bank
    2003Agricultural Development Bank
    2004ARB Apex Bank Limited
    2005Bank of Africa
    2006Bank of Ghana
    2007CalBank PLC
    2008Consolidated Bank Ghana Limited
    2009Ecobank Ghana Limited
    2010Fidelity Bank Ghana Limited
    2011First Atlantic Bank Limited
    2012First National Bank (Ghana) Limited
    2013GCB Bank Limited
    2014Guaranty Trust Bank (Ghana) Limited
    2015National Investment Bank Limited
    2016Prudential Bank Limited
    2017Republic Bank (Ghana) PLC
    2018Stanbic Bank Ghana Limited
    2019Standard Chartered Bank (Ghana) Limited
    2020OmniBSIC Bank
    2021United Bank of Africa
    2022Universal Merchant Bank Limited
    2023Zenith Bank (Ghana) Limited
    2024First Bank of Nigeria
    2025Societe Generale Ghana

    9. Security Best Practices#

    Never expose your secret or private key in client-side code.
    Do not commit keys to GitHub or other version control systems.
    Rotate keys regularly.
    Validate callbacks by checking signatures (if provided).

    10. Developer Tools#

    Postman Collection: (Coming Soon)
    Sandbox Environment: https://sandbox.junipayments.com
    Webhook Events: transaction.success, transaction.failed, transaction.pending
    Modified at 2026-06-19 08:41:38
    Next
    Authentication
    Built with