Accept a payment

Learn how to use Fintoc's API to accept one-time payments

There are three steps to accept payments using Fintoc:

  1. On your backend, create a Checkout Session using your Secret Key
  2. Redirect your user to complete the payment on the Fintoc-hosted checkout page
  3. Handle post-payments events

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

Optional: install our backend SDK

If you’re using Python, you can install our Python SDK to make it easier to interact with our API. The SDK automatically handles pagination, lets you easily verify Fintoc's webhooks, and offers many other helpful features.

pip install fintoc

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.

Using your Secret Key, create a Checkout Session from your backend with the required parameters: amount, currency, success_urland cancel_url like the example bellow:

curl --request POST "https://api.fintoc.com/v2/checkout_sessions" \
  --header "Authorization: YOUR_TEST_SECRET_API_KEY" \
  --header "Content-Type: application/json" \
  --data-raw '{
    "amount": 350000,
    "currency": "CLP",
    "success_url": "https://merchant.com/success",
    "cancel_url": "https://merchant.com/987654321",
    "customer": {
      "tax_id": {
        "type": "cl_rut",
        "value": "12088191"
      },
      "name": "Felipe Castro",
      "email": "[email protected]",
      "metadata": {}
    },
    "metadata": {
      "order": "987654321"
    }
  }'
const { Fintoc } = require('fintoc');

const fintoc = new Fintoc('YOUR_SECRET_KEY');

const checkoutSession = await fintoc.checkoutSessions.create({
  amount: 1000,
  currency: 'mxn',
  customer_email: '[email protected]'
});
from fintoc import Fintoc

client = Fintoc('YOUR_TEST_SECRET_API_KEY')

checkout_session = client.checkout_sessions.create(
  amount=1000,
  currency='clp',
  customer_email='[email protected]'
)
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)

Parameter

Example

Description

amount

2476

Required amount 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.

currency

CLP

Required currency that is being used for the payment. We currently support CLP and MXN.

success_url

https://merchant.com/success

Required URL to redirect the user in case of payment succeeded.

cancel_url

https://merchant.com/987654321

Required URL to redirect the user in case they decide to cancel the payment and return to your website.

metadata

{"order": "987654321"}

Optional set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.

📘

Send the Business Profile object if you are processing payments for a submerchant

You can also add the business_profile object when creating a session to customize the name displayed as the "Recipient" on the payment flow.

Read here to learn more.

Include Customer Data (Optional)

When creating a Checkout Session, you can include customer information. This allows Fintoc to display only the available payment methods for that specific customer, such as verifying if the amount exceeds the transaction limit for a selected bank in the payment initiation method.

Attribute

Type

Description

tax_id

object

Object that identifies the customer at a fiscal or regulatory level.

It includes a type field indicating the format or country-specific identifier (for example, "cl_rut" for Chilean RUT) and a value field containing the actual tax identification number as a string.

One of tax_id or email is required

name

string

Optional full name of the customer.

email

string

Customer email linked to a Checkout Session. This is used to notify a user in case of a refund.

One of tax_id or email is required

metadata

object

Optional custom data that can store additional information about the customer (e.g., internal IDs, CRM references, or tags)

Pre-select a Payment Method (Optional)

You can create a Checkout Session without specifying payment methods. In this case, users can select from all available options on the Fintoc-hosted checkout page, based on the session parameters (amount, customer, currency) and the payment methods you have enabled in Fintoc.

Alternatively, you can explicitly define the payment method(s) for the session. For example, in the request below, the payment_initiation method is set, combined with payment_method_options, where the institution cl_banco_estado is pre-selected for the user. In this scenario, the payment flow presented to the user will be limited to this specific method and bank.

curl --request POST "https://api.fintoc.com/v2/checkout_sessions" \
  --header "Authorization: YOUR_TEST_SECRET_API_KEY" \
  --header "Content-Type: application/json" \
  --data-raw '{
    "amount": 350000,
    "currency": "CLP",
    "success_url": "https://merchant.com/success",
    "cancel_url": "https://merchant.com/987654321",
    "payment_methods": ["payment_initiation"],
    "payment_method_options": {
      "payment_initiation": {
        "institution_id": "cl_banco_estado"
      }
    },
    "customer_data": {
      "tax_id": {
        "type": "cl_rut",
        "value": "12088191"
      },
      "name": "Felipe Castro",
      "email": "[email protected]",
      "metadata": {}
    }
  }'
const { Fintoc } = require('fintoc');

const fintoc = new Fintoc('YOUR_SECRET_KEY');

const checkoutSession = await fintoc.checkoutSessions.create({
  amount: 1000,
  currency: 'mxn',
  customer_email: '[email protected]'
});
from fintoc import Fintoc

client = Fintoc('YOUR_TEST_SECRET_API_KEY')

checkout_session = client.checkout_sessions.create(
  amount=1000,
  currency='clp',
  customer_email='[email protected]'
)
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)
AttributeTypeDescription
payment_methodsarray of stringsOptional definition of the available payment method(s) for the session. Methods current available are payment_intent (bank transfers) and card
payment_method_optionshashOptional array of settings for each available payment method

Left: Default view showing all available methods (bank transfer and cards) when no payment_method parameter is set. Center: Pre-selected bank transfer flow for Banco Estado, displaying the institution-specific payment form directly. Right: Pre-selected cardflow.

📘

Using your own Checkout Page

When you have your own checkout page, you should set the payment_method to redirect users to the Fintoc-hosted checkout after they've already selected their preferred payment method.

This skips Fintoc's payment method selection screen and directs users straight to the specific payment flow, instead of letting Fintoc manage the full checkout experience.

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",
  "object": "checkout_session",
  "mode": "test",
  "status": "created",
  "amount": 350000,
  "currency": "CLP",
  "created_at": "2024-06-04T15:32:46.721Z",
  "updated_at": "2024-06-04T15:32:46.721Z",
  "success_url": "https://merchant.com/success",
  "cancel_url": "https://merchant.com/987654321",
  "redirect_url": "https://checkout.fintoc.com/checkout_session_01HXY3Z7X5YQ54V8G2E1KJQAVF",
  "metadata": {},
  "customer": {
    "name": "Felipe Castro",
    "email": "[email protected]",
    "metadata": {},
    "tax_id": {
      "type": "cl_rut",
      "value": "12088191"
    }
  }
}

In the response, you should receive the redirect_url attribute. In the following step, you'll use this attribute to redirect the user to complete the payment.

Redirect the user to complete the payment

Next, you will redirect users to the Fintoc-hosted checkout page. After completing the payment, they'll be automatically redirected back to your site.

Based on the payment result, the user will be redirected to either the success or cancel URL.

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 backend, you will use the events sent by webhooks.

Complete the payment on your backend

Fintoc sends a checkout_session.finished and a payment_intent.succeeded event when the session completes and the payment is successful. 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 session and the payment_intent:

{
  "id": "evt_a4xK32BanKWYn",
  "object": "event",
  "type": "checkout_session.finished",
  "data": {
    "id": "cs_li5531onlFDi235",
    "mode": "test",
    "amount": 350000,
    "object": "checkout_session",
    "status": "finished",
    "currency": "CLP",
    "metadata": {},
    "cancel_url": "https://merchant.com/987654321",
    "created_at": "2026-01-13T18:48:25Z",
    "expires_at": "2026-01-14T18:48:25Z",
    "success_url": "https://merchant.com/success",
    "redirect_url": "https://checkout.fintoc.com/checkout_session_01HXY3Z7X5YQ54V8G2E1KJQAVF",
    "session_token": null,
    "customer_email": null,
    "customer": {
      "name": "Felipe Castro",
      "email": "[email protected]",
      "metadata": {},
      "tax_id": {
        "type": "cl_rut",
        "value": "12088191"
      }
    },
    "payment_methods": [
      "payment_intent"
    ],
    "business_profile": {},
    "payment_resource": {
      "payment_intent": {
        "id": "pi_38DNJo3rbvGUzKFvCGZ6dxR1Kxx",
        "mode": "test",
        "amount": 350000,
        "object": "payment_intent",
        "status": "succeeded",
        "currency": "CLP",
        "metadata": {},
        "created_at": "2026-01-13T18:48:31Z",
        "expires_at": "2026-01-14T18:48:25Z",
        "error_reason": null,
        "payment_type": "bank_transfer",
        "reference_id": null,
        "widget_token": null,
        "customer_email": null,
        "sender_account": {
          "type": "checking_account",
          "number": "813990168",
          "holder_id": "415792638",
          "institution_id": "cl_banco_falabella"
        },
        "business_profile": {},
        "transaction_date": null,
        "recipient_account": null,
        "payment_type_options": {}
      }
    },
    "payment_method_options": {}
  }
}

You should handle the following post-payment events :

EventDescriptionAction
checkout_session.finishedSent when a payment associated to a Checkout Session reaches a final stateComplete the order based on the payment's status
checkout_session.expiredSent when a session expiresOffer the customer another attempt to pay.
payment_intent.succeededSent when the payment related to a checkout session succeeds.Confirm the customer's order
payment_intent.failedSent when the payment related to a checkout session fails.Offer the customer another attempt to pay.
📘

Handling async payments after the Checkout Session ends

In some cases, the Checkout Session may finish with a payment that does not yet have a final status, such as requires_action. This can happen, for example, when a bank transfer from a business account requires approval from more than one representative.

In these cases, you should inform the user that the payment is pending approval. Once you receive either the payment_intent.succeeded or payment_intent.failed event, you should notify the user of the final payment status as soon as it is confirmed.

Test your integration

Using your test mode API Secret Key, you can create payments that simulate successful and failed outcomes without moving any money.

This lets you validate your full payment flow end-to-end:

  • Your backend API requests (creating sessions and handling responses)
  • The redirect flow from your frontend to the redirect_url and back to the success_url or cancel_url after the payment
  • Webhook for post-payment events

To learn how to trigger specific scenarios, use the test credentials and special test values described in our testing guide.