Accept a payment
Learn how to use Fintoc's Payment Initiation API
There are three steps to accept payments using Fintoc:
- On your backend, create a
Checkout Session
using your Secret Key - Open the widget on your frontend using your Public Key and the Session Token
- 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.
Parameter | Example | Explanation |
---|---|---|
amount | 2476 | 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 | Currency 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 thecheckout_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:
Event | Description | Action |
---|---|---|
checkout_session.finished | Sent when a payment associated to a Checkout Session reaches a final state | Complete the order based on the payment's final status |
checkout_session.expired | Sent when a session expires | Offer the customer another attempt to pay. |
Updated about 9 hours ago