Developer Documentation

Merchant Integration Guide

Payments API v1

A production-oriented guide for integrating Pementek payments, hosted checkout, asynchronous verification, idempotency and signed webhooks into your website or application.

Version1.0 Draft
Updated8 October 2026
AudienceMerchants & Developers
Publishing note

This document is written as the public merchant-facing integration guide. Internal provider routing, device-health thresholds, provider limits and operational algorithms are intentionally not exposed. API fields should be kept synchronized with the final backend implementation before production launch.

Contents

Use this guide as the canonical public integration reference for Pementek merchants.

  1. Overview
  2. Quick start
  3. Authentication & environments
  4. Create a payment
  5. Idempotency & merchant references
  6. Hosted Checkout
  7. Payment lifecycle
  8. Retrieve payment status
  9. Webhooks
  10. Webhook signature verification
  11. Webhook delivery & deduplication
  12. Errors, retries & timeouts
  13. Payment methods & markets
  14. Merchant-side data model
  15. Integration examples
  16. Security best practices
  17. Customer experience guidance
  18. Sandbox testing & launch checklist
  19. Payouts / withdrawals - API preview
  20. Glossary & support

1. Overview

Pementek provides a unified API and hosted checkout for local payment methods. Merchants create a payment on their backend, redirect the customer to Pementek Checkout, and update their own system only after Pementek reports the verified result through a signed webhook or server-side status query.

Create payment from your backend
        |
        v
Redirect to Pementek Checkout
        |
        v
Customer completes local payment
        |
        v
Pementek verifies the transaction
        |
        v
Your backend receives the result
Core rule

A browser redirect is never proof of payment. Credit a customer only from a verified server-to-server result.

Integration model

Customer Browser
      |
      v
Your Website / App ----> Your Backend
                              |
                              v
                         Pementek API
                              |
                              v
                       Pementek Checkout
                              |
                              v
                         Local Payment
                              |
                              v
                          Verification
                              |
                              v
                    Signed Webhook to You

Designed for multiple markets

The API contract is country-, currency- and payment-method aware. Market availability is enabled per merchant account. The initial implementation can launch market-by-market while preserving the same integration model for future local payment methods.

2. Quick start

The shortest production-safe integration has four responsibilities: authenticate from your backend, create a payment with an idempotency key, redirect the customer to the returned checkout URL, and process signed webhook events exactly once.

1. Store API credentials server-side
2. POST /v1/payments
3. Redirect to checkout_url
4. Verify and process webhooks

Base URLs

PurposeURL
Production APIhttps://api.pementek.com/v1
Hosted Checkouthttps://pay.pementek.com
Documentationhttps://docs.pementek.com
SandboxA separate sandbox base URL can be enabled for testing.
Do not hardcode unpublished endpoints

Keep production and sandbox endpoints in environment configuration. Never ship production credentials into browser JavaScript or mobile application bundles.

Minimal create-payment request

curl -X POST "https://api.pementek.com/v1/payments" \
  -H "Authorization: Bearer $PEMENTEK_API_KEY" \
  -H "Idempotency-Key: order-847291-payment-1" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_reference": "ORDER-847291",
    "amount": 1500.00,
    "currency": "BDT",
    "country": "BD",
    "payment_method": "BKASH",
    "return_url": "https://merchant.example/payment/return"
  }'

3. Authentication & environments

API credentials authenticate your merchant backend. They must never be exposed to the customer. Use different credentials for sandbox and production, and rotate credentials when staff, servers or security posture changes.

Authentication header

Authorization: Bearer YOUR_API_KEY

Where credentials may live

LocationAllowed?Reason
Backend environment / secret managerYesServer-side and access controlled.
Browser JavaScriptNoAny visitor can inspect the bundle or requests.
Mobile app packageNoApp binaries can be inspected or instrumented.
Public Git repositoryNoSecrets can be harvested and reused.
CI/CD secret storeYesUse least-privilege access and protected environments.
Recommended practice

Issue separate credentials per environment and, where practical, per production application. This makes revocation and audit easier.

4. Create a payment

Create a payment only from your server. A successful response returns the Pementek payment identifier and a hosted checkout URL. Persist both the Pementek ID and your own merchant reference before redirecting the customer.

Endpoint

POST /v1/payments

Request fields

FieldTypeRequiredDescription
merchant_referencestringYesYour unique order, deposit or transaction reference.
amountdecimalYesRequested amount in the selected currency.
currencystringYesISO-style currency code, for example BDT.
countrystringYesMarket code, for example BD.
payment_methodstringYesEnabled local method, for example BKASH or NAGAD.
customer.referencestringNoYour internal customer/user reference. Do not send secrets.
return_urlURLRecommendedWhere the browser may return after checkout.
metadataobjectNoSmall merchant-defined values useful for reconciliation.

Example response

{
  "id": "PMT-PAY-20261008-X82F91",
  "merchant_reference": "ORDER-847291",
  "type": "PAYMENT",
  "status": "CREATED",
  "amount": 1500.00,
  "currency": "BDT",
  "country": "BD",
  "payment_method": "BKASH",
  "checkout_url": "https://pay.pementek.com/p/PMT-PAY-20261008-X82F91",
  "created_at": "2026-10-08T03:05:21Z"
}
Important

Use the returned checkout_url. Do not construct a Pementek checkout URL yourself.

5. Idempotency & merchant references

Network timeouts can make it unclear whether a payment was created. Idempotency lets you retry the same logical create request without accidentally creating a second financial transaction.

Idempotency-Key

Idempotency-Key: order-847291-payment-1
SituationCorrect behaviour
First create attemptSend a new unique idempotency key for the logical payment.
HTTP timeout / connection resetRetry with the same idempotency key.
User intentionally starts a different paymentUse a new key and a new merchant reference as appropriate.
Duplicate webhookDo not use create-payment idempotency; deduplicate by webhook event_id.
Never retry with random keys

If every retry uses a new key, the merchant can accidentally create multiple valid payments for one order.

Merchant reference

merchant_reference links your record to the Pementek payment. It should be unique within the appropriate merchant scope and must be stored in your database together with the returned Pementek payment ID.

6. Hosted Checkout

Pementek Checkout handles the customer-facing payment instructions and verification hand-off. The customer can be redirected tocheckout_url from a web application or opened in an appropriate browser context from a mobile application.

Open checkout_url
      |
      v
Payment route is prepared
      |
      v
Instructions are shown
      |
      v
Customer completes payment
      |
      v
Customer confirms completion
      |
      v
Verification starts

Return URL is not authoritative

The return URL is a convenience for browser navigation. A user can close the page, refresh it, manipulate navigation history or revisit the URL later. Your backend must therefore ignore browser navigation as a financial signal.

Recommended return-page UI

Show “Checking payment status…” and query your own backend. Your backend can serve the latest Pementek status or wait for the webhook.

Unavailable payment capacity

A selected method can temporarily have no eligible processing capacity. Pementek may place the payment inWAITING_FOR_PROVIDER for a short routing window. This is not a financial failure because the customer has not yet been instructed to send money.

ROUTING
  |
  +-- provider available --> AWAITING_USER_CONFIRMATION
  |
  +-- none available ------> WAITING_FOR_PROVIDER
                                  |
                                  +-- becomes available --> continue
                                  |
                                  +-- window expires ----> ROUTING_UNAVAILABLE

7. Payment lifecycle

Integrations must support asynchronous payment states. Do not collapse every non-success state into “failed”.

StatusMerchant meaning
CREATEDPayment resource exists.
ROUTINGPementek is preparing processing capacity.
WAITING_FOR_PROVIDERSelected method is temporarily waiting for capacity.
AWAITING_USER_CONFIRMATIONCheckout instructions are available and the customer can complete payment.
VERIFYINGPementek is verifying transaction evidence.
PENDING_RECONCILIATIONVerification is not yet conclusive; do not ask the customer to pay again.
MANUAL_REVIEWThe transaction requires operational review.
SUCCESSThe payment has been verified. This is the positive terminal result.
FINAL_FAILEDPementek has definitively failed the payment.
ROUTING_UNAVAILABLEThe selected payment method could not obtain capacity in the routing window.
CANCELLEDThe payment was cancelled.
EXPIREDThe payment session expired.

Pending does not mean failed

Verification can be delayed by temporary connectivity or evidence delivery conditions. A payment may therefore move fromPENDING_RECONCILIATION toSUCCESS later. Your business logic must allow that transition.

Customer experience

When a payment is pending, tell the customer not to pay again. A second real-world payment can create a duplicate-payment support case.

8. Retrieve payment status

Use the status endpoint for server-side reconciliation, customer return pages, support tooling and recovery from missed or delayed webhooks.

Endpoint

GET /v1/payments/{payment_id}

Example

curl "https://api.pementek.com/v1/payments/PMT-PAY-20261008-X82F91" \
  -H "Authorization: Bearer $PEMENTEK_API_KEY"

Example response

{
  "id": "PMT-PAY-20261008-X82F91",
  "merchant_reference": "ORDER-847291",
  "status": "SUCCESS",
  "amount": 1500.00,
  "currency": "BDT",
  "payment_method": "BKASH",
  "created_at": "2026-10-08T03:05:21Z",
  "completed_at": "2026-10-08T03:06:48Z"
}
Verification before crediting

Match the Pementek payment ID, merchant reference, amount and currency against your stored record before applying any customer credit.

9. Webhooks

Webhooks are the recommended way to receive final and important asynchronous status updates. Pementek may retry an event until your endpoint acknowledges it successfully, so handlers must be idempotent.

Typical events

payment.pending
payment.succeeded
payment.failed

Example payload

{
  "event_id": "evt_01K7XX9J4JFA",
  "event": "payment.succeeded",
  "created_at": "2026-10-08T03:06:48Z",
  "data": {
    "id": "PMT-PAY-20261008-X82F91",
    "merchant_reference": "ORDER-847291",
    "status": "SUCCESS",
    "amount": 1500.00,
    "currency": "BDT",
    "country": "BD",
    "payment_method": "BKASH"
  }
}

Webhook endpoint behaviour

1. Receive raw request
2. Verify signature
3. Check event_id
4. Store/process safely
5. Return HTTP 2xx

10. Webhook signature verification

A webhook must be authenticated before it changes financial state in your system. Use the raw request body when computing the signature. Parsing and re-serializing JSON can change whitespace or field ordering and break verification.

Suggested headers

Pementek-Event-Id: evt_01K7XX9J4JFA
Pementek-Timestamp: 1791428808
Pementek-Signature: sha256=...

Signing model

signed_payload = timestamp + "." + raw_request_body
expected = HMAC_SHA256(webhook_secret, signed_payload)
  • Reject signatures that do not match using a constant-time comparison.
  • Reject timestamps outside your acceptable replay window.
  • Store event_id and process each event exactly once in your business layer.
  • Keep webhook signing secrets server-side and rotate them under a controlled procedure.
Implementation note

The final production header names and canonical signing string must be treated as part of the API contract. Keep this page synchronized with the backend implementation and SDKs.

11. Webhook delivery & deduplication

Pementek uses at-least-once delivery semantics. Your endpoint can receive the same event multiple times because the original response may have been lost, delayed or non-successful.

event evt_123 arrives
        |
        v
Is event_id already processed?
     |                 |
    yes               no
     |                 |
ignore safely     verify transaction
                       |
                       v
                    apply once
                       |
                       v
                  mark processed

Recommended persistence

Table/fieldPurpose
pementek_webhook_events.event_idUnique key used to deduplicate delivery.
payment_idLinks event to the payment stored by your merchant system.
processed_atAudit evidence that the event was consumed.
payload_hash (optional)Useful for operational diagnostics and tamper detection.
Fast acknowledgement

Verify and persist the event, then return HTTP 2xx promptly. Move expensive business work to your own durable queue when appropriate.

12. Errors, retries & timeouts

Applications should rely on stable error codes rather than parsing human-readable messages. A transient network error must not be interpreted as proof that a payment was never created.

Example error

{
  "error": {
    "code": "INVALID_AMOUNT",
    "message": "The supplied payment amount is invalid.",
    "request_id": "req_01K7XY..."
  }
}
HTTPMeaning / action
200Successful request.
201Resource created.
400Invalid request.
401Authentication failed.
403Operation not permitted.
404Resource not found.
409Conflict or duplicate semantic request.
422Valid format but cannot be processed.
429Rate limit exceeded; retry according to policy.
500Temporary server error; retry safe operations.
503Service temporarily unavailable.

Common error codes

AUTHENTICATION_FAILED
INVALID_REQUEST
INVALID_AMOUNT
UNSUPPORTED_CURRENCY
UNSUPPORTED_COUNTRY
PAYMENT_METHOD_UNAVAILABLE
DUPLICATE_REFERENCE
RATE_LIMITED
INTERNAL_ERROR
Timeout rule

Browser timeout != payment failure. HTTP timeout != payment failure. Verification delay != payment failure. Retry creation with the same idempotency key or query the existing payment status.

13. Payment methods & markets

Payment method availability can vary by country, currency, merchant account, transaction amount and current channel availability. Merchants should avoid permanently hardcoding a global list of methods into their product.

Capabilities endpoint

GET /v1/payment-methods?country=BD&currency=BDT

Example response

{
  "country": "BD",
  "currency": "BDT",
  "methods": [
    {
      "code": "BKASH",
      "name": "bKash",
      "payment_enabled": true
    },
    {
      "code": "NAGAD",
      "name": "Nagad",
      "payment_enabled": true
    }
  ]
}
Market rollout

Pementek is designed for local-payment expansion across multiple markets, but public documentation should list a market or method as live only after it is operationally enabled.

Alternative methods

If the customer selects a method that becomes temporarily unavailable, do not silently switch them to another method. Show the unavailable state and let the customer explicitly choose another enabled method.

14. Merchant-side data model

Pementek does not replace your own order or customer ledger. Your system should maintain a local payment record that links your business transaction to the Pementek resource.

Minimum recommended fields

pementek_payment_id
merchant_reference
customer_id
amount
currency
payment_method
status
created_at
updated_at
completed_at

Webhook event table

event_id       UNIQUE
payment_id
event_type
processed_at

Credit exactly once

BEGIN DATABASE TRANSACTION

  lock local payment row
  verify local payment not already credited
  verify Pementek status == SUCCESS
  verify payment_id / reference / amount / currency
  credit customer or fulfill order
  mark local payment credited
  store event_id processed

COMMIT
Financial safety

The operation that applies customer credit and marks the event/payment processed should be atomic in your own database whenever possible.

15. Integration examples

Node.js / server-side JavaScript

const response = await fetch(
  "https://api.pementek.com/v1/payments",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${'{'}process.env.PEMENTEK_API_KEY{'}'}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "order-847291-payment-1"
    },
    body: JSON.stringify({
      merchant_reference: "ORDER-847291",
      amount: 1500.00,
      currency: "BDT",
      country: "BD",
      payment_method: "BKASH",
      return_url: "https://merchant.example/payment/return"
    })
  }
);

const payment = await response.json();

PHP

<?php

$payload = [
  "merchant_reference" => "ORDER-847291",
  "amount" => 1500.00,
  "currency" => "BDT",
  "country" => "BD",
  "payment_method" => "BKASH",
  "return_url" => "https://merchant.example/payment/return"
];

$ch = curl_init(
  "https://api.pementek.com/v1/payments"
);

curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("PEMENTEK_API_KEY"),
    "Content-Type: application/json",
    "Idempotency-Key: order-847291-payment-1"
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);

$response = curl_exec($ch);

16. Security best practices

Merchant security is part of the end-to-end payment security model. A correct Pementek integration can still become unsafe if the merchant trusts browser state, exposes API keys or processes webhook events more than once.

  • Use HTTPS for every production endpoint.
  • Store API keys and webhook secrets only on trusted backend systems.
  • Verify every webhook signature before reading it as an authoritative event.
  • Use idempotency keys for create operations and event_id deduplication for webhooks.
  • Validate payment ID, merchant reference, amount and currency before crediting a user.
  • Use MFA and role-based access for merchant dashboard users.
  • Keep production and sandbox credentials separate.
  • Keep audit logs for payment state changes and manual operational actions.
  • Never request or store a customer mobile-money PIN or OTP as part of your Pementek integration.
Sensitive data minimization

Send only transaction data Pementek actually needs. Do not attach passwords, OTP codes, PINs, full identity documents or unrelated personal data in metadata.

17. Customer experience guidance

Good status messaging reduces duplicate payments and support load. The customer should always understand whether they need to take an action or simply wait for verification.

StateRecommended customer message
WAITING_FOR_PROVIDER“Preparing this payment method. Please wait a moment…”
AWAITING_USER_CONFIRMATIONShow the Pementek payment instructions.
VERIFYING“We are verifying your payment.”
PENDING_RECONCILIATION“Your payment is still being verified. You do not need to pay again.”
SUCCESS“Payment confirmed.”
ROUTING_UNAVAILABLE“This payment method is temporarily unavailable. Try again or choose another method.”
FINAL_FAILED“The payment could not be completed.”
Do not expose internals

Do not show provider counts, provider balances, cooldowns, device health, routing priorities or provider identity details. These are internal Pementek infrastructure concerns.

18. Sandbox testing & launch checklist

A merchant integration is not production-ready until failure, delay and duplicate-delivery cases are tested. Happy-path testing alone is insufficient for a financial workflow.

Minimum test scenarios

  • Successful payment and successful webhook processing.
  • Payment that remains pending before later success.
  • Definitively failed payment.
  • Duplicate create request with the same idempotency key.
  • Duplicate webhook delivery with the same event_id.
  • Webhook endpoint temporarily unavailable, then recovered.
  • Customer closes checkout before return.
  • Selected payment method temporarily unavailable.
  • Invalid amount or unsupported currency.
  • Invalid credentials and permission errors.
  • Network timeout during create-payment request.
  • Mismatch between webhook amount/reference and merchant local record.

Production launch checklist

19. Payouts / withdrawals - API preview

Preview only

Payout support is a planned extension of the same merchant platform. Do not integrate against this section until the Payout API is enabled and marked stable for your merchant account.

The intended payout model lets a merchant submit an approved withdrawal to a supported personal wallet. Pementek processes the transfer asynchronously and reports the verified result through the same server-to-server principles used for payments.

Customer requests withdrawal
        |
        v
Merchant approves it
        |
        v
Create Pementek payout
        |
        v
Pementek processes transfer
        |
        v
Receive verified payout webhook

Proposed endpoint

POST /v1/payouts

Proposed request

{
  "merchant_reference": "WD-829182",
  "amount": 1000.00,
  "currency": "BDT",
  "country": "BD",
  "payment_method": "BKASH",
  "recipient": {
    "wallet_type": "PERSONAL",
    "wallet_number": "017XXXXXXXX"
  }
}

Payouts should also be treated asynchronously. The merchant should mark a customer withdrawal complete only after Pementek returns the verified SUCCESS result through the supported API/webhook contract.

20. Glossary & support

TermMeaning
MerchantThe business integrating Pementek.
PaymentA customer-to-merchant collection transaction processed through Pementek.
PayoutA merchant-initiated transfer to a customer wallet when this feature is enabled.
Hosted CheckoutPementek customer-facing flow at pay.pementek.com.
Idempotency keyA merchant-supplied key that makes retries of the same create operation safe.
WebhookA signed server-to-server event sent by Pementek to the merchant.
Pending reconciliationA non-final payment state in which verification is still unresolved.
Merchant referenceThe merchant's own unique business transaction reference.

Support information

For production documentation, publish your merchant support channel, operational status page and escalation process here. Recommended destinations include the merchant dashboard support area andstatus.pementek.com.

Canonical public contract

Once the backend is live,docs.pementek.com should be the canonical public source for endpoint URLs, field names, status values, webhook signature rules and SDK examples. Update the site documentation and this PDF together.

Pementek — Local payments. One integration.

Merchant Integration Guide — API v1 — Draft 1.0