Accept a payment

Learn how to use Fintoc's Payment Initiation API

There are three steps to accept payments using Fintoc:

  1. On your backend, create a Checkout Session using your Secret Key
  2. Open the widget on your frontend using your Public Key and the Session Token
  3. Handle post-payments events

The following diagram shows how Fintoc interacts with both your backend and your frontend

Create a session

The Checkout Session object represents your intent to collect a payment from a customer and tracks state changes throughout the payment process.

Before creating a Session, you must decide how to operate with Fintoc. The recommended way β€”and the defaultβ€” is that Fintoc collects your payments and then makes payouts to your bank account based on a payout schedule. If you want the money to be sent directly to a specific bank account, see the setup direct payments guide.

Using your Secret Key, create a Checkout Session on your server with an amount and currency.

curl --request POST "https://api.fintoc.com/v1/checkout_sessions" \
-- header 'Authorization: YOUR_TEST_SECRET_API_KEY' \
-- header 'Content-Type: application/json' \
--data-raw '{
  "amount": 2476,
  "currency": "CLP",
  "customer_email":"[email protected]"
}'
const fetch = require('node-fetch');

const checkout_session = {
  amount: 1000,
  currency: 'clp',
  customer_email:'[email protected]'
}

fetch('https://api.fintoc.com/v1/checkout_sessions', {
  	method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'YOUR_TEST_SECRET_API_KEY'
    },
    body: JSON.stringify(checkout_session),
  },
)
import requests

checkout_session = {
  'amount': 1000,
  'currency': 'clp',
  'customer_email':'[email protected]'
}

headers = {
  'Accept': 'application/json', 'Authorization': 'YOUR_TEST_SECRET_API_KEY'
}

r = requests.post(
  'https://api.fintoc.com/v1/checkout_sessions',
  json=checkout_session,
  headers=headers
)
require 'net/http'
require 'uri'
require 'json'

checkout_session = {
  amount: 1000,
  currency: 'clp',
  customer_email: '[email protected]'
}

uri = URI("https://api.fintoc.com/v1/checkout_sessions")

header = {
  Accept: 'application/json', Authorization: 'YOUR_TEST_SECRET_API_KEY'
}

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = checkout_session.to_json

response = http.request(request)

If you want to create a Checkout Session for Mexico, change the currency to MXN.

🚧

Currencies are represented as integers

The Fintoc API represents currencies in its smallest possible units with no decimals (as an integer). That means that an amount of MXN 10.29 gets represented by Fintoc as 1029. You can read more about currencies here.

ParameterExampleExplanation
amount2476Amount of money that needs to be paid. It's represented as integer with no decimals in the smallest possible unit of the currency you are using.

If your payment uses Chilean peso, an amount of CLP 2476 is represented as 2476.

If your payment uses Mexican peso, an amount of MXN 24.76 is represented as 2476.

Read here to learn more.
currencyCLPCurrency that is being used for the payment. We currently support CLP and MXN.

Response when creating a Checkout Session

After making the request to create the Checkout Session, Fintoc should respond with something like this:

{
  id: "cs_li5531onlFDi235",
  created_at: "2021-10-15T15:22:11.474Z",
  object: "checkout_session",
  currency: "CLP",
  amount: 2476,
  customer_email: "[email protected]",
  expires_at: "1718634045", // UTC Timestamp
  mode: "test",
  return_url: "https://example.com/return?id=cs_li5531onlFDi235",
  status: "created",
  session_token: "cs_li5531onlFDi235_sec_a4xK32BanKWYn",
  metadata: {},
}

In the response, you should receive the session_token attribute. In the following step, you'll use this attribute to set up the Fintoc widget.


πŸ“˜

The session token is temporary

The session_token is temporary and will expire 10 minutes after its creation.

Open the widget

Once you create the Checkout session, you need to use the session_token to setup the widget for a payment.

The Fintoc Widget is the client-side component that your customers will interact with to pay using Fintoc. The Fintoc Widget will handle credential validation, multi-factor authentication, and error handling for each institution that we support.

Use your Public Key and the Session Token to configure the widget.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0">
    <title>Fintoc Demo</title>
    <script src="https://js.fintoc.com/v1/"></script>
  </head>
  <body>
    <script>
      window.onload = () => {
        const widget = Fintoc.create({
          sessionToken: 'cs_XXXXXXXX_sec_YYYYYYYY',
          product: 'payments',
          publicKey: 'YOUR_PUBLIC_KEY',
          onSuccess: () => {},
        });
        widget.open();
      };
    </script>
  </body>
</html>

If you want a Mexican payment, change the country parameter to mx.

You can read more about the widget and its configurations in the Widget guide.

πŸ“˜

Use our Widget Webview if you are building a mobile app

If you are integrating Fintoc into an iOS or Android application, you can use our WebView integration.

Handle post-payments events

Once a Checkout Session finishes, you handle the payment result in your frontend and complete the payment in your backend. For your frontend you will use the widget callback, and for your backend you will use the events sent by webhooks.

πŸ“˜

Use webhooks events to complete payments

Your customer could close the browser window or quit the app before the onSuccess widget callback executes. For this reason, you should always use the checkout_session.finished event to handle post-payments actions like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Handle the payment result on your frontend

Once a Payment associated to the Checkout Session finishes successfully, the widget executes the onSuccess callback. You need to pass this function to the widget upon creation.

With this callback, you can decide what to do with your user's frontend once the payment is complete, for example:

  • Redirect the user to a post-sale or post-payment view
  • Show the user a success screen.

πŸ“˜

Don't use this callback as a payment confirmation

You shouldn't trust on the onSuccess callback as a confirmation for a successful payment, as the frontend is an insecure realm and a malicious third party may execute a JavaScript function that simulates that the transfer was executed successfully.

For a more comprehensive validation mechanism, we strongly encourage integrating webhooks and subscribing to the checkout_session.finished event. By implementing webhooks, you can ensure timely and accurate updates on payment statuses, enhancing the overall security and reliability of your payment confirmation process.

Handle errors

You don't only need to handle succeeded payments because payments can also fail. For example, your customer doesn't have funds in their bank account to complete the payment.

When a payment fails or is rejected by your customer, the widget executes the onExit callback. With this callback, you can handle errors on your frontend. For example, you can invite your customer to use another payment method.

Complete the payment on your backend

Fintoc sends a checkout_session.finished event when the payment completes. Use the follow the webhook guide to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

The checkout_session.finished event includes information about the related payment, and looks like this:

{
  "id": "evt_a4xK32BanKWYn",
  "object": "event",
  "type": "checkout_session.finished",
  "data": {
    id: "cs_li5531onlFDi235",
    created_at: "2021-10-15T15:22:11.474Z",
    object: "session",
    currency: "clp",
    amount: 1200,
    customer_email: "[email protected]",
    expires_at: "1718634045",
    product: "payments",
    mode: "live",
    return_url: "https://example.com/return?id={CHECKOUT_SESSION_ID}",
    status: "succeeded",
    session_token: "cs_li5531onlFDi235_sec_a4xK32BanKWYn",
    type: "embedded",
    country: 'cl',
    metadata: {
    	order_id: "#12513"
  	},
    payment_methods: [
      'fintoc_transfer'
    ],
    payment_method_options: {
      payment_intent: {
        holder_type: 'individual',
        recipient_account: {
          "holder_id": "183917137",
          "number": "123456",
          "type": "checking_account",
          "institution_id": "cl_banco_de_chile"
        },
        sender_account: {
          holder_id: {
            editable: 'false',
            value: 123456789
          },
          institution_id: {
            editable: 'false',
            value: 'cl_banco_estado'
          }
        }
      }
    },
    payment_intent: {
      "id": "pi_BO381oEATXonG6bj",
      "object": "payment_intent",
      "amount": 1200,
      "currency": "CLP",
      "status": "succeeded",
      "reference_id": "90123712",
      "transaction_date": "2021-10-15T15:24:15.474Z",
      "metadata": {
        order_id: "#12513"
      },
      "error_reason": null,
      "recipient_account": {
        "holder_id": "183917137",
        "number": "123456",
        "type": "checking_account",
        "institution_id": "cl_banco_de_chile"
      },
      "sender_account": {
        "holder_id": "192769065",
        "number": "123456",
        "type": "checking_account",
        "institution_id": "cl_banco_estado"
      },
      "created_at": "2021-10-15T15:23:11.474Z"
    }
  }

You should handle the following events when using our Payment Initiation product:

EventDescriptionAction
checkout_session.finishedSent when a payment associated to a Checkout Session reaches a final stateComplete the order based on the payment's final status
checkout_session.expiredSent when a session expiresOffer the customer another attempt to pay.