Payment intents
Learn how to collect immediate payments using Pluto.
Payment intent lifecycle
All payment intents start as requires_confirmation
. They can be updated to succeeded
, failed
, or canceled
.
requires_confirmation
: Pluto is waiting for a transaction associated with the payment intent to be finalized on-chain.succeeded
: The payment intent has succeeded and the transaction has been finalized on-chain.failed
: The payment intent has failed. Payment failures can result from events such as on-chain transaction failures or malicious payment attempts.canceled
: The payment intent has been canceled.
In this diagram, a payment intent is created via the Pluto API. Once the payment intent is retrieved on the frontend, the user is prompted to confirm the transaction from their wallet. The transaction is sent to Pluto's smart contract, which splits the payment among the specified wallets.
Typically, the payment will be split between two wallets: your account's payout wallet and Pluto's payout wallet (used for collecting a transaction fee). However, payments can be split between an unlimited number of wallets. This can be useful for an online marketplace, for example. Whenever a product is sold, the revenue is split between the merchant and the marketplace. Pluto's multiparty payments features allow you to easily build this functionality.
Finally, Pluto listens for the transaction to be finalized on-chain. After performing validation, it either fails or succeeds the payment intent. Additionally, Pluto handles transactions that are dropped and replaced.
You can execute logic determined by the outcome of the payment intent by setting up a webhook and listening for the payment_intent.succeeded
and payment_intent.failed
events.
Create a payment intent
Creating a payment intent can be done by passing any of the following combinations:
- An
invoice
- A
price
andcustomer
- An
amount
,currency
,chain
, andcustomer
If you pass an invoice, Pluto can determine the rest of the relevant information from the invoice, such as the amount to charge. This can be useful in integrations such as a custom invoice payment page.
const { Pluto } = require('@plutohq/pluto-node');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);
await pluto.paymentIntents.create({ invoice: '{{INVOICE_ID}}' });
Passing a price
allows you to easily create payment intents with the same amount. Additionally, this allows you to charge the same fiat amount (e.g. $30 in ETH) if the price has a base_price
property.
Payment intents with adjustable pricing
If you use an adjustable price, you will need to specify an
amount
when creating the payment intent.
const { Pluto } = require('@plutohq/pluto-node');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);
await pluto.paymentIntents.create({
price: '{{PRICE_ID}}',
customer: '{{CUSTOMER_ID}}',
});
You can also specify an amount manually when creating a payment intent.
const { Pluto } = require('@plutohq/pluto-node');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);
const paymentIntent = await pluto.paymentIntents.create({
amount: 0.5,
currency: 'eth',
chain: 'eth',
customer: '{{CUSTOMER_ID}}',
});
Add line items to a payment intent
If line items are added, the total amount to be charged will be calculated by summing each line item and an amount
, if it exists. This can be useful for separating a base charge for an item from an initial fee. You can add as many line items as needed.
const { Pluto } = require('@plutohq/pluto-node');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);
await pluto.paymentIntents.create({
price: '{{PRICE_ID}}',
customer: '{{CUSTOMER_ID}}',
line_items: [
{ price_data: { amount: 0.25 } },
],
});
Pay a payment intent
Use one of our client-side libraries to pay a payment intent. This will prompt the user to confirm the transaction from their wallet.
const transaction = await plutoJS.confirmPayment('{{PAYMENT_INTENT_ID}}');
Cancel a payment intent
Payment intents can be canceled at any time. However, if a payment intent has an associated transaction processing on-chain, cancelling the payment intent will not automatically refund the transaction.
const { Pluto } = require('@plutohq/pluto-node');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);
await pluto.paymentIntents.cancel('{{PAYMENT_INTENT_ID}}');
Updated 6 months ago