Finbility Payment
Developer Documentation

Accept card payments with one frontend script and a standard backend API.

finbility-card.js is the merchant-side entry point. It renders the secure card UI, loads Evervault automatically, encrypts sensitive fields in the browser, and writes the result back to your form for submission.

Overview

Integration model

Finbility provides a standard REST payment API plus a merchant-side secure card component. The frontend component is delivered through finbility-card.js, which wraps Evervault card fields behind a simpler integration surface.

  • Frontend renders one secure card block and writes encrypted values into your form.
  • Backend uses OAuth 2.0, then calls payment, query, webhook, and refund APIs.
  • Default selectors, hidden field mappings, and built-in copy keep checkout integration minimal.

Prerequisites

  • Client ID and Client Secret for Finbility OAuth.
  • A backend service that generates the checkout token for the page.
  • A checkout page served over HTTPS.

Base URL

Sandbox: https://test.openapi.finbility.io
OAuth 2.0

Get an access token before calling backend APIs

POST /v1/oauth/token?grant_type=client_credentials&scope=write,read
Header Required Description
Authorization Yes Basic + Base64(clientId:clientSecret)
Accept Yes application/json
Content-Type Yes application/x-www-form-urlencoded
{
  "access_token": "653633b2-8287-47b6-a7e4-40ec252fe9a8",
  "token_type": "bearer",
  "expires_in": 43035,
  "scope": "write,read"
}
Use the returned token as Authorization: Bearer <access_token> when calling payment and refund APIs.
Frontend

Use finbility-card.js as the merchant integration layer

The script automatically loads the Evervault browser SDK, generates the secure card UI inside your mount element, manages loading and error states, enables the submit button when the encrypted payload is ready, and writes values into hidden inputs.

  • The component handles secure fields, default copy, loading state, and hidden field updates.
  • You control token delivery, locale, theme, callbacks, form action, and backend payload mapping.
  • The default integration only needs one script tag, one mount div, and one submit button.
Real checkout pages only need one script tag and one mount div to get started. Hidden inputs are optional from the component perspective, but keeping them in markup is still a good way to make the submit payload easy to understand.
Quick Start

Minimal integration

  1. Include finbility-card.js on the checkout page.
  2. Add a form with a single mount container and a submit button.
  3. Pass a backend-generated token.
  4. Submit the form only after controller.hasEncryptedPayload() is true.
<script src="/web/js/finbility-card.js"></script>

<form id="credit_card_form" action="/standard/credit_card" method="post" novalidate>
  <div id="finbility-pay-card"></div>

  <input type="hidden" name="cardNumber" id="finbility-pay-card-number">
  <input type="hidden" name="expirationMonth" id="finbility-pay-expiration-month">
  <input type="hidden" name="expirationYear" id="finbility-pay-expiration-year">
  <input type="hidden" name="cvNumber" id="finbility-pay-cv-number">

  <button type="submit" id="js-pay-btn" disabled="disabled">Pay</button>
</form>

<script>
  var controller = window.FinbilityPayCard.create({
    token: "BASE64_TOKEN_FROM_BACKEND",
    locale: "en_US"
  });

  document.getElementById("credit_card_form").addEventListener("submit", function (event) {
    event.preventDefault();

    if (!controller || controller.isFailed()) {
      return;
    }

    if (!controller.hasEncryptedPayload()) {
      return;
    }

    this.submit();
  });
</script>
The component injects its own internal card shell, hints, loading state, and service notice. Merchants only need to provide the mount container.
Configuration

Token, hidden fields, and customization

The public integration entry point is token. Hidden inputs can be pre-rendered by the merchant form or created automatically by the component, and the rest of the checkout behavior can be customized through selectors, messages, theme, and callbacks.

{
  "token": "BASE64_TOKEN_FROM_BACKEND"
}
Generate tokens on the backend. Do not hardcode permanent credential values into public sample pages or production templates.
Option Type Description
token string Backend-generated checkout token used to initialize the secure card component.
locale string Built-in locales: en_US and zh_CN.
selectors object Override mount, form, and submitButton.
hiddenFields object Override hidden field ids and names. If matching fields already exist in the form, the component reuses them.
messages object Override default field labels, placeholders, hints, and status copy.
theme object Override colors, radius, and text sizes without changing the integration model.
cardOptions object Pass supported Evervault card options such as field set or color scheme.
onReady, onError, onChange, onStateChange function Lifecycle callbacks for host page control and analytics.

Example with custom selectors and hidden field ids

window.FinbilityPayCard.create({
  token: "BASE64_TOKEN_FROM_BACKEND",
  locale: "zh_CN",
  selectors: {
    mount: "#custom-pay-card",
    form: "#custom-form",
    submitButton: "#submit-btn"
  },
  hiddenFields: {
    number: { id: "encryptedCardNumber", name: "cardNumber" },
    expiryMonth: { id: "encryptedMonth", name: "expirationMonth" },
    expiryYear: { id: "encryptedYear", name: "expirationYear" },
    cvc: { id: "encryptedCvc", name: "cvNumber" }
  }
});

Browser expectations

  • finbility-card.js is implemented in ES5 style for broad browser compatibility.
  • Target current versions of Chrome, Edge, Safari, and Firefox for merchant checkout pages.
  • The script loads the Evervault browser SDK internally, so merchants only need to include one JS file.
Backend

Send the encrypted payload to the payment API

Your backend receives the form submission, maps the encrypted values to Finbility request fields, and calls the payment endpoint with your OAuth access token.

POST /v1/paymentDirect

Request headers

Header Required Description
Authorization Yes Bearer <access_token>
Accept Yes application/json
Content-Type Yes application/json

Core request fields

Parameter Required Description
order_idYesMerchant order number, unique per payment attempt.
payment_methodYesPayment method code, for example EECPB_3D.
amountYesTransaction amount with two decimals.
currencyYesISO currency code, for example USD or EUR.
request_typeYesRequest source, for example WEB, WAP, or SDK.
descriptionYesOrder description. Avoid /, =, and &.
return_urlYesRedirect URL after payment completion.
notify_urlYesWebhook URL for payment result notifications.
websiteYesMerchant website URL.
cardnumYesEncrypted card number from cardNumber.
cardexpiryYesConcatenate month and year to MMYY format.
cardcvvYesEncrypted security code from cvNumber.
sourceYesCustomer object described below.
Only card number and CVC are encrypted by the frontend component. Expiry month and year remain plain text, so your backend should assemble cardexpiry from those two fields.

Customer source fields

Parameter Required Description
client_ipYesCustomer IP address.
first_nameYesCustomer first name.
middle_nameNoCustomer middle name.
last_nameYesCustomer last name.
countryYesISO country code, for example US or CN.
stateConditionalRequired for US and CA card payments.
cityYesCity name.
zipConditionalRequired for US and CA card payments.
emailYesCustomer email address.
address1YesPrimary address line.
address2NoSecondary address line.
phoneYesPhone number.
cpfNoBrazilian tax ID when required by method or region.
{
  "return_url": "https://merchant.example/return",
  "notify_url": "https://merchant.example/notify",
  "payment_method": "EECPB_3D",
  "request_type": "WEB",
  "order_id": "100096247512",
  "amount": "1.00",
  "currency": "USD",
  "description": "Product Title",
  "website": "https://merchant.example",
  "cardnum": "ev:encrypted:card-number",
  "cardexpiry": "0926",
  "cardcvv": "ev:encrypted:cvc",
  "source": {
    "first_name": "Chris",
    "middle_name": "",
    "last_name": "Ma",
    "country": "US",
    "state": "CA",
    "city": "Los Angeles",
    "zip": "90001",
    "email": "test@example.com",
    "phone": "1-555-0100",
    "address1": "100 Main Street",
    "address2": "Suite 18",
    "client_ip": "203.0.113.10",
    "cpf": ""
  }
}

3DS browser header

BrowserInfo: {"acceptHeader":"application/json","language":"en","userAgent":"Mozilla/5.0","javaEnabled":"true","colorDepth":"24","screenHeight":"1080","screenWidth":"1920","timeZoneOffset":"-480"}
Payment Response

Response and query flow

The create-payment response and the payment query response share the same core structure.

GET /v1/payment/{payment_id}
Field Description
payment_idFinbility payment identifier.
transaction_idPlatform transaction identifier.
statusCurrent payment status.
error_codeError code when a payment does not succeed.
remarksHuman-readable failure reason.
pay_urlRedirect URL when the method requires an external step.
{
  "payment_id": "65df5a6791a211e583461c6f65f84b6d",
  "transaction_id": "72c17f2d91a211e583461c6f65f84b6d",
  "create_time": "2015-07-07T08:05:38Z",
  "update_time": "2015-07-07T08:05:38Z",
  "payment_method": "EECPB_3D",
  "status": "SUCCESS",
  "error_code": "",
  "remarks": "",
  "order_id": "100096247512",
  "description": "Product Title",
  "amount": "1.00",
  "currency": "USD",
  "request_type": "WEB",
  "pay_url": "https://..."
}
Webhook

Payment result notification

Finbility sends a POST request to your notify_url when the payment result is available.

Field Description
transaction_idPlatform transaction identifier.
order_idMerchant order number.
payment_idFinbility payment identifier.
payment_methodPayment method code.
error_messageFailure reason, empty on success.
statusCurrent transaction status.
{
  "transaction_id": "72c17f2d91a211e583461c6f65f84b6d",
  "order_id": "100096247512",
  "payment_id": "65df5a6791a211e583461c6f65f84b6d",
  "payment_method": "EECPB_3D",
  "error_message": "",
  "status": "SUCCESS"
}
Refund

Refund by order id

POST /v1/refund/{order_id}
Header Required Description
AuthorizationYesBearer <access_token>
AcceptYesapplication/json
Content-TypeYesapplication/json

Refund request body

Parameter Required Description
amountYesRefund amount.
currencyYesCurrency code.
refund_order_idYesMerchant refund order number, unique per refund.
descriptionNoOptional refund description.
{
  "amount": "1.00",
  "currency": "USD",
  "refund_order_id": "R20260414001",
  "description": "Customer requested refund"
}

Refund query

GET /v1/refund/{refund_id}

The response returns the refund identifier, status, amount, currency, timestamps, and any failure reason.

Reference

Status and error handling

Typical payment statuses

  • SUCCESS: payment completed.
  • FAILED: payment could not be completed.
  • PROCESSING: payment is still being processed.
  • PENDING: payment is waiting for a downstream step or confirmation.

Integration checks

  • Ensure the checkout page is served over HTTPS.
  • Do not submit until the card controller reports an encrypted payload.
  • Log webhook callbacks and reconcile them with payment query results.
  • Handle token expiry and OAuth refresh on the backend.
If the card component enters an error state, block payment submission and surface a retry path. The built-in UI already exposes service-unavailable copy and a refresh action; the host page should respect that state instead of forcing form submission.