Checkout

Flutter checkout SDK

Open VenPays hosted card checkout inside a Flutter WebView. Card numbers never touch your app — the shopper pays on the VenPays / Mastercard page.

This version is card only (venpays_flutter 0.1.2). Benefit, BenefitPay, and Apple Pay are not in the Flutter SDK yet. For native Apple Pay on iOS, see Apple Pay iOS.


Credentials

CredentialWhere it livesWhat it does
Secret (sk_…) or existing unprefixed keyYour merchant backendCreates the checkout session, starts card pay, confirms status
Publishable (pk_…)Not required for this Flutter flowUsed by the JavaScript checkout SDK only

Never put a secret or legacy key in the Flutter app. The SDK never accepts or stores VenPays API keys.


1. Create a session and start card pay 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" }

Then start card payment:

POST /v1/sdk/checkout/{track_id}/pay
Host: init-vpay.venlabs.link
Content-Type: application/json

{ "method": "card" }

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

Return only safe fields to the app:

{
  "track_id": "…",
  "payment_url": "https://…/mastercard/payment?payment_id=…",
  "amount": 12.5,
  "currency": "BHD"
}

2. Install the Flutter package

dependencies:
  venpays_flutter: ^0.1.2
flutter pub get

Package: venpays_flutter
Source: venpays-flutter


3. Start checkout in the app

import 'package:venpays_flutter/venpays_flutter.dart';

final result = await VenPaysCheckout.start(
  context: context,
  paymentUrl: payment.paymentUrl, // from your backend
  trackId: payment.trackId,       // from your backend
  successUrl: 'https://merchant.example/payment/success',
  failureUrl: 'https://merchant.example/payment/failure',
);

switch (result.status) {
  case PaymentStatus.success:
    // Informational only — confirm on your backend before fulfillment.
    break;
  case PaymentStatus.failed:
    break;
  case PaymentStatus.cancelled:
    // Shopper closed checkout; transaction is marked cancelled on VenPays.
    break;
  case PaymentStatus.error:
    break;
}
FieldRequirement
paymentUrlHTTPS hosted card URL from POST …/pay
trackIdSession track_id from your backend
successUrl / failureUrlSame HTTPS Profile (or override) return URLs VenPays will redirect to

Custom URL schemes (myapp://…) are not supported by the Payment Engine return-URL validator. See Return URLs.

While the sheet is open, the SDK polls GET /v1/sdk/checkout/{track_id}/status on the Payment Engine host from paymentUrl. When status becomes success, failed, or cancelled, the sheet dismisses automatically — even if the Profile return URL does not exactly match what you passed in.

If the shopper closes the sheet while the payment is still pending, the SDK calls POST /v1/sdk/checkout/{track_id}/cancel so the transaction is marked cancelled on VenPays (not left pending). Closing after a finished payment still reports success/failure, not cancelled.

If the customer never pays, VenPays cancels the payment after 30 minutes even when the sheet stays open. Payment-status then returns cancelled.

PaymentResult is still client-observed only. Confirm on your server before fulfillment.


4. Confirm on your server

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

Abandoned checkouts should show status: "cancelled" on POST /merchant/payment-status.


Sandbox and live

The Flutter app does not choose sandbox vs live. Your backend selects the environment by which Payment Engine host and API key it uses; the app only opens the payment_url you return.

EnvironmentPayment Engine
Sandboxhttps://init-vpay.venlabs.link
Livehttps://merchant.venpays.com

What the Flutter SDK does not do

  • Collect or store card PAN / CVV
  • Hold secret, legacy, or publishable keys
  • Call initiate, refund, or merchant payment-status APIs
  • Select Benefit, BenefitPay, or Apple Pay

It may poll the public checkout status endpoint and call cancel on abandon for UX. That is not a substitute for merchant-server confirmation.


Troubleshooting

SymptomCheck
Validation error “must use https”Use HTTPS for paymentUrl, successUrl, and failureUrl
Sheet does not auto-closeEnsure the device can reach GET /v1/sdk/checkout/{track_id}/status on the same PE host as payment_url; prefer matching Profile return URLs too
App shows cancelled but dashboard still pendingUse Payment Engine build with cancel support + venpays_flutter ≥ 0.1.2; confirm with POST /merchant/payment-status
App shows cancelled but dashboard shows successUpdate to venpays_flutter ≥ 0.1.1 (status re-check on close); confirm with webhooks / payment-status
Success in app but order not paidConfirm with POST /merchant/payment-status / webhooks
Blank WebViewDevice network, Payment Engine / gateway reachability, invalid payment_url