PayElect Developer
Docs / Guides / Hosted Checkout

Hosted Checkout

Hosted checkout is the simplest integration. PayElect renders the payment page — your customer is redirected to a PayElect-hosted URL, selects a provider, authenticates, and completes payment. You receive the result via a return redirect and a webhook.

You do not need to build or style a payment form. PCI scope is minimal because no card data transits your servers.

Flow overview

#ActorAction
1Your serverPOST /authentication/token → receive access_token
2Your serverPOST /payment/create with amount, currency, return_url, cancel_url → receive payment_url
3Your serverHTTP 302 redirect the customer to payment_url
4CustomerSelects provider on PayElect checkout page, authenticates with wallet, confirms payment
5PayElectProcesses the payment, fires payment.succeeded webhook to your endpoint
6PayElectRedirects customer browser to your return_url with result params in query string
7Your serverWebhook handler verifies HMAC signature, fulfils the order
Return URL params are not authoritative. Always fulfil the order from the webhook, not from the return redirect. A malicious user could craft a fake success redirect.

Creating the payment

A minimal payment create request:

curl -X POST https://api.payelecthq.com/pay/api/v1/payment/create \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "150000",
    "currency": "GNF",
    "country": "GN",
    "return_url": "https://shop.example.com/orders/8821/confirm",
    "cancel_url": "https://shop.example.com/orders/8821/cancel",
    "custom": "order_8821",
    "idempotency_key": "ord-8821-v1"
  }'

Response:

{
  "status": "success",
  "data": {
    "token": "pymt_01J4ABCDEFGHIJKLMNOPQRSTU",
    "payment_url": "https://api.payelecthq.com/pay/v1/user/authentication/form/pymt_01J4ABCDEFGHIJKLMNOPQRSTU"
  }
}

Handling the return URL

After payment completes (success, failure, or cancellation), the customer's browser is redirected to your return_url or cancel_url. Query string params are appended:


GET /orders/8821/confirm
  ?type=success
  &data[token]=pymt_01J4ABCDEFGHIJKLMNOPQRSTU
  &data[trx_id]=TRX0000012345678
  &data[amount]=150000
  &data[custom]=order_8821
  &message[code]=200


GET /orders/8821/confirm
  ?type=error
  &data[token]=pymt_01J4ABCDEFGHIJKLMNOPQRSTU
  &message[code]=402
  &message[error][0]=Payment+was+declined

Recommended return URL handler (PHP/Laravel):

public function paymentReturn(Request $request, $orderId): Response
{
    // Show a "processing" page immediately; rely on webhook for fulfilment.
    // Never fulfil the order here — webhook hasn't been verified yet.
    $type = $request->query('type');

    return match ($type) {
        'success' => view('orders.processing', ['orderId' => $orderId]),
        'pending' => view('orders.pending',    ['orderId' => $orderId]),
        default   => view('orders.failed',     ['orderId' => $orderId,
                           'error' => $request->input('message.error.0')]),
    };
}