Payments Quickstart

Securely collect payment details from your customers and create a charges.


Accepting payments using FayaPay is a two-step process, with a client-side and a server-side action:

  1. From your website running in the customer’s browser, FayaPay securely collects your customer’s payment details and returns a Source. The id of the source, along with any other form data is then submitted to your server.
  2. Your server-side code makes an API request to create a Charge and complete the payment.

This process ensures that no sensitive data ever needs to touch your server, so your integration can be seamless and easy. Payment details are never fully revealed, though limited information is provided by the api and dashboard (such as the last four characters and payment provider).


Step 1 Securely collecting payment details

The simplest way for you to securely collect payment details is with the Checkout SDK. It creates a payment form and handles the collection of payment details on your behalf. When your customer enters their payment details, this is validated and converted to a source, which your server-side code can use to create charges.

To see checkout in action, click the button below, filling in the resulting form:

Creating your payment button

To get started, you must first create a form that will submit the information to your server.

Add a button (or input) that can submit the form, and specify the data attributes required to configure checkout. Ensure that the button has the css class of .fp-btn as this is required by the SDK for automatic detection of payment buttons.

<form action="/place-order" method="post">
    <!-- 
        you can put whatever form inputs you want here.
        they will be posted along with the source id.
    -->          
    <button 
        type="submit" 

        <!-- required -->
        class="fp-btn"
        data-pubkey="{{ public-key }}"
        data-amount="100"
        data-currency="GHS"
        data-return-url="https://domain.com/complete-order/order-id"

        <!-- optional -->
        data-logo="https://url/to/logo.png"
        data-name="John Mokudi"
        data-email="example@domain.com"
        data-description="Checkout Example"

        <!-- optional metadata -->
        data-metadata-key1="Value1"
        data-metadata-key2="Value2">Pay</button>
</form>

Replace the data-pubkey attribute with your test publishable key to test this code through your FayaPay account. When you’re ready to go live, you must replace the test key with your live key. Learn more about how keys play into test and live modes.

The amount must be a whole integer in the smallest currency denomination e.g. to charge 1 GHS, you should pass in 100 pesewas. A good rule of thumb is to multiply the amount by 100.

The SDK supports multiple buttons on the same page.

Buttons must have the .fp-btn css class and must be embedded in a form.

Next, you need to install the SDK by adding the following script tag just before the closing </body> of your webpage.

    <script
        src="https://cdn.fayapay.io/fayapay.v1.js"
        type="text/javascript"></script>

Step 2 Creating a charge to complete the payment

After the customer provides their payment details and a source is created, the form is posted to your server.
The form will include a new input, fp_source_id which contains the id of the newly created source.

Using this id, your server-side code should make an API request to retrieve the source.

curl -X GET 'https://api.fayapay.io/v1/sources/{{ source-id }}' \
    -H 'Authorization: {{ api-key }}'

Once you've retrieved your source successfully, you should handle any additional steps required to complete the source creation.

You should link the source and customer's order. This can be in your database or by utilizing the source metadata. This is important as payment flows asynchronous and you need to track state.

Redirect Flow

Some payment channels expect additional steps to be carried out such as entering a token, scanning a code or a redirect. The SDK handles all of these flows except the Redirect.

You are required to handle this in your server side code. In pseudo javascript:

if(source.flow == "Redirect") {
    return redirect(source.redirectUrl);
}

After the customer has completed creating the source, they are redirected back to the data-return-url you provided when creating the button.

Creating the charge

If the source state is Chargeable or you've received the source.chargeable event webhook you can now proceed to create the charge.

Your server-side code should make an API request to create a one-time charge.
This request requires the reference, source, currency, amount, and any additional information you may want to pass (e.g. description, metadata).

curl -X POST 'https://api.fayapay.io/v1/charges' \
    -H 'Authorization: {{ api-key }}' \
    -H "X-Idempotency-Key: {{ your-unique-reference }}" \
    -H 'Content-Type: application/json' \
    -d '{ 
            "reference": "{{ your-unique-reference }}", 
            "source": "{{ source-id }}", 
            "amount": 100, 
            "currency": "GHS",
            "description": "Checkout Example",
        }'

Setting the Idempotency key handles any race conditions and allows you to repeat the call safely. The result of the initial call will be retured to subsequent callers.

Idempotency keys are cached for 12 hours and are not guaranteed to satisfy idempotency after that.

Sources can only be used once, and within a limited time after creation. To prevent your customers from needing to re-enter their payment details each time they make a purchase, you can attach sources to customers for later use. Using this method, returning customers can quickly make a payment without providing their payment details again.

Confirming the charge

FayaPay does not provide a synchronous charge confirmation flow.
You are expected to implement a webhook receiver to listen for Account Events and react accordingly.

Listen for the charge.successful or charge.failed events to update the state of your order accordingly.

The user can be redirected to a confirmation page that periodically polls the status of the order.
Polling can be timed out after a number of tries and customer informed that they will be notified when their payment is confirmed.

For more information on how to handle the customer notification flow, see our sample integration.