Checkout

JavaScript checkout SDK

Embed a card checkout widget on your page. The shopper pays on the VenPays hosted card page — card numbers never touch your site or this SDK.

This version is card only (@venpays/checkout 0.2.2). Benefit, BenefitPay, and Apple Pay are not available in the widget yet; use hosted checkout for those methods.


Credentials

CredentialWhere it livesWhat it does
Secret (sk_…) or existing unprefixed keyYour serverCreates the checkout session and sets the amount
Publishable (pk_…)BrowserActivates the widget and selects sandbox vs live from the prefix. Cannot charge, refund, or set the amount

Never put a secret or legacy key in frontend JavaScript. The publishable key only identifies your merchant. Restrict it to your checkout origins in the dashboard if you want.


1. Create a session on your server

POST /v1/sdk/checkout
Host: init-vpay.venlabs.link
X-API-KEY: sk_test_…
Content-Type: application/json

{ "amount": 12.500, "currency": "BHD" }

Live host: merchant.venpays.com. Use a secret or legacy key, not the publishable key.

The response includes track_id. Pass that id to your checkout page.


2. Load the widget

Prefer the public CDN (same script for sandbox and live; the publishable key picks the API host):

<div id="venpays-checkout"></div>
<script src="https://cdn.venpays.com/v0.2.2/venpays-checkout.js"></script>
<script>
  VenPays.init({
    publishableKey: "pk_test_…",
    trackId: "TRACK_ID_FROM_YOUR_SERVER",
  }).then(function (checkout) {
    checkout.mount("#venpays-checkout");
  });
</script>

Pin a version (/v0.2.2/…) in production. Avoid /latest/ unless you accept unannounced upgrades.

Or install from npm for bundlers:

npm install @venpays/checkout
import VenPays from "@venpays/checkout";

const checkout = await VenPays.init({
  publishableKey: "pk_test_…",
  trackId: "TRACK_ID_FROM_YOUR_SERVER",
});
checkout.mount("#venpays-checkout");
Publishable keyEngine the SDK calls
pk_test_…Sandbox (init-vpay.venlabs.link)
pk_live_…Live (merchant.venpays.com)

init checks the publishable key, then loads the session. The session includes merchant_name from your merchant profile. The shopper clicks pay and is redirected to the hosted card page, which shows your merchant name, logo, and website. See Cards.

The browser package lives in venpays-js-sdk — not in the Payment Engine repo.


3. Confirm on your server

After the shopper returns, treat the browser status as a hint only. Fulfill the order from a webhook or POST /merchant/payment-status with your secret key. See Payment status and Webhooks.

Optional browser poll after return:

const result = await VenPays.complete({ publishableKey: "pk_test_…" });
// reads track_id from the query string
// status: pending | success | failed | cancelled

4. Cancel if the shopper abandons checkout

If the shopper closes your checkout UI before paying, mark the session cancelled so it does not stay pending:

await checkout.cancel();
// or without a Checkout instance:
await VenPays.cancel({
  publishableKey: "pk_test_…",
  trackId: "TRACK_ID_FROM_YOUR_SERVER",
});

That calls POST /v1/sdk/checkout/{track_id}/cancel on the Payment Engine. It is idempotent: already success / failed / cancelled is left unchanged. After cancel, POST /merchant/payment-status returns cancelled.

Do not call cancel after a successful redirect to the hosted card page — that payment may still complete.

If the customer never pays, VenPays cancels the payment after 30 minutes. Payment-status then returns cancelled without a cancel call.


What the publishable key cannot do

  • Create a session or set the amount
  • Call initiate, refund, or merchant status APIs
  • Substitute for X-API-KEY on your server

If you send a publishable key as X-API-KEY, the Payment Engine rejects the request.