Payment Intents
Payment intents represent an intent to collect payment from or send a payment to a contact. Truss has two kinds of payment intent:
| Kind | direction |
Contact | Wallet | Endpoints |
|---|---|---|---|---|
| Inbound payment intent (invoice) | 0 |
Customer who pays the company. Include whenever customer information is available. | Receiving wallet | /v1/payment-intents/inbound/ |
| Outbound payment intent (bill) | 1 |
Vendor the company pays. Required. | Funding wallet | /v1/payment-intents/outbound/ |
Inbound and outbound payment intents share the same PaymentIntent response shape but are created, listed and managed through separate endpoints and scopes.
Contacts
A payment intent may be attached to a contact. A contact has a name and email associated to it, which is used to notify contacts to send or receive payment. An optional phone number may also be added.
- On an inbound payment intent, the contact is the customer, sent as
contacton create. Always includecontactwhen you have an existing Truss contact or the customer's name and email. Omit it only as a fallback when customer contact information is unavailable; this creates a contactless payment intent. Contacts on inbound payment intents may have an optional secondary email with which a payment intent can be paid. - On an outbound payment intent, the contact is the vendor, sent as
vendoron create. It is required.
In both cases, provide the uid of an existing contact, or a name and email. A provided uid or a matching name uses and updates the existing contact; otherwise a new contact is created.
In both sandbox and production contacts receive emails and SMS notifications related to the payment intent and resulting transactions. Ensure a real email address and SMS enabled phone number is used.
Existing contacts can be retrieved and updated via API. A contact's name, email, secondary email and phone number may be updated. See API References for more details.
Wallets
A company may have more than one wallet (bank account) in Truss. Every payment intent is booked to one company wallet:
- An inbound payment intent is booked to the receiving wallet, which receives the customer's payments.
- An outbound payment intent is booked to the funding wallet, which pays the vendor.
List the company's wallets with GET /v1/wallets/ (requires wallets:read). Each wallet has a uid, an is_primary flag, a name and the last four digits of its account number (mask).
To choose the wallet, send its uid as wallet_uid when creating the payment intent. If wallet_uid is omitted, the company's primary wallet is used. A wallet_uid that does not belong to the company returns a 422 validation error on wallet_uid.
Payment intent responses include the booked wallet as a read-only wallet_uid. The wallet cannot be changed via API after the payment intent is created.
Transactions
A payment intent may have one or more related transactions. When a contact sends a payment or receives a payment, a transaction is created.
Transactions either increment or decrement the balance_paid amount on their payment intent, depending their direction. For example, for an transaction on an inbound payment intent, a direction of 0 would increment the balance_paid while a direction of 1 would decrement the balance. In this scenario, the inbound-direction transaction is a payment made by the contact towards the payment intent while the outbound-direction transaction is likely a return or refund.
Payment Intent Statuses & Lifecycle
Payment intents progress through several statuses:
| Status | Description |
|---|---|
Pending |
The initial status of newly created payment intents awaiting payment |
PartiallyPaid |
The payment intent has been partially paid (balance_paid != total) |
Paid |
The payment intent has been fully paid (balance_paid == total) |
Canceled |
The payment intent has been canceled |
Draft |
(Outbound payment intents only) A payment on the bill has been submitted in Truss and is waiting for admin approval. This status is not achievable via API |
Failed |
(Outbound payment intents only) The payment intent has a returned transaction (the payment has failed). This state is not achievable via API |
Errored |
(Inbound payment intents only) The payment intent has an error related to the integrated accounting system. This state is not achievable via API |
Inbound Payment Intents
Creating an inbound payment intent
In Truss, each company account is required to set up a Payment Portal link in order to create inbound payment intents and begin accepting payments from their customers. Once set up, inbound payment intents can be created by users via the Truss web client or mobile app, via an accounting integration, or via API. Newly created inbound payment intents will have a Pending status.
Send wallet_uid to choose the receiving wallet; see Wallets.
Choosing between a contact and contactless checkout
The contact you send when creating the payment intent determines which customer is assigned to the invoice in Truss and which checkout experience they use. Customer information in your product is not automatically passed to Truss.
| Behavior | With contact (recommended whenever available) |
Without contact (contactless fallback) |
|---|---|---|
| Customer on the invoice in Truss | The supplied customer is assigned. | No customer is assigned at creation. |
| Checkout experience | The customer verifies their email and pays through the Payment Portal. | The payer starts guest checkout using the returned checkout_url. |
| Saved payment methods | The verified customer can use their available saved payment methods and save supported methods for future payments. | While paying as a guest, the payer must enter payment details. They cannot use saved payment methods or save methods for future payments. |
checkout_url in the API response |
null; use a Payment Portal link. |
A guest checkout link for this payment intent. |
An integration can use both flows: include a contact for customers whose information you have, and use contactless creation only for those whose contact information is unavailable.
Creating an inbound payment intent with a contact
Send POST /v1/payment-intents/inbound/ with an existing Truss contact UID:
{
"total": "100.00",
"addenda": "Invoice INV-1001",
"contact": {
"uid": "3dba9d05-bb20-423e-924e-4b19e50d6f3c"
}
}
The UID above is illustrative. Use a contact belonging to the company creating the invoice, not a customer ID from your own product.
If you do not have a Truss contact UID, send the customer's name and email in the same create request:
{
"total": "100.00",
"addenda": "Invoice INV-1001",
"contact": {
"name": "Alex Customer",
"email": "alex@example.com"
}
}
Truss uses and updates a matching contact or creates a new one; see Contacts. You do not need to create the contact in a separate API call. Send the customer to the Payment Portal, where they verify the contact's primary or secondary email to access the invoice and their available saved payment methods.
Accepting payment on an inbound payment intent
A Payment Portal is a unique link generated for each Truss company. Companies are able to distribute this link via their preferred channel to give their customers a platform to view and pay payment intents which the company has sent to them to be paid. All Pending, PartiallyPaid and Paid inbound payment intents related to the customer are available to view in the Payment Portal. Pending and PartiallyPaid can be selected by customers to pay via one of the available payment methods. Once a customer pays, a transaction is created and the payment intent will move to a PartiallyPaid or Paid status, depending on if there is a remaining balance on the payment intent.
Integration partners can open the Payment Portal directly on a payer’s inbound payment intent via a deep link and optionally return users to their own app. See Partner Payment Portal for more details.
Contactless inbound payment intents
Use contactless creation only when customer contact information is unavailable. Send POST /v1/payment-intents/inbound/ without contact:
{
"total": "100.00",
"addenda": "Invoice INV-1001"
}
The invoice has no customer assigned in Truss at creation. The payer starts guest checkout and must enter their payment details; while paying as a guest, they cannot use saved payment methods or save methods for future payments.
- No notifications are sent.
send_emailorsend_smsset totruewithout acontactreturns a422validation error. - The response includes a
checkout_url: a guest checkout link for this payment intent. Share it with the payer through your own channel. checkout_urlis returned on create, retrieve, update and cancel responses. It is omitted from list responses and webhook payloads, and isnullfor payment intents that have a contact.
Payment intents with a contact are paid through the Payment Portal instead; see Partner Payment Portal.
Customer exists in your product but is missing on the Truss invoice
If your product has the customer's information but the invoice is created without a customer in Truss, check the request to POST /v1/payment-intents/inbound/. Omitting contact creates a contactless invoice even when that customer already exists in Truss. Truss does not infer the customer from the invoice description, memo, or customer information stored in your product.
To prevent this, include contact in the create request: send the existing Truss contact UID, or the customer's name and email as shown above. Route the customer to the Payment Portal after creation. The contactless flow remains available as a fallback for other invoices whose customer information is unavailable.
The Foundation API's update endpoint does not accept contact, so it cannot attach a customer to an already-created invoice. Include the contact at creation to avoid requiring a company user to assign the customer manually in Truss.
Funds availability for payments
Once a customer pays a Truss company the inbound transaction is subject to a settlement period while the funds arrive and clear in the Truss bank account. During this time, the funds are immediately available to spend to create outbound transactions in Truss or spend on Truss cards. Once sufficient inbound transactions are settled, the outgoing transactions complete processing and are sent to their destination.
Outbound Payment Intents
Creating an outbound payment intent
Create a bill with POST /v1/payment-intents/outbound/:
total,addendaandvendorare required.vendortakes theuidof an existing vendor, or anameandemail; see Contacts.note,memoanddue_dateare optional.wallet_uidis optional and chooses the funding wallet; see Wallets.
A company cannot create a bill to pay itself. Newly created outbound payment intents have a Pending status.
The Foundation API records the bill only. It does not create draft payments or pay the bill. A company user pays the bill in the Truss dashboard.
Paying a bill in the Truss dashboard
After creating a bill, send a company user to the Pay bill form for it, using the uid from the create response:
Production:
https://app.trusspayments.com/dashboard/bills?view=pay-bill&id=new&paymentIntentUid={uid}
Sandbox:
https://app.staging.trusspayments.com/dashboard/bills?view=pay-bill&id=new&paymentIntentUid={uid}
To let the user review the bill before paying, link to the bill detail on the same host instead:
/dashboard/bills?view=payment-intent&id={uid}
The user signs in to Truss as usual. The link is kept through login, two-factor verification and company selection. Opening it does not start a payment; the user chooses how to pay and confirms in the form. A user without access to the bill's company is not shown the bill or the payment form.
These dashboard links are for company users paying their own bills. They are separate from the Payment Portal, where customers pay a company's inbound payment intents.
Updating and canceling an outbound payment intent
total,addendaandnotecannot be updated once a bill is partially paid, fully paid or canceled.memoanddue_datecan be updated at any time.- A bill cannot be canceled once it is fully paid or already canceled, or while it has a payment that has not been returned, refunded or canceled.
Payment intent webhooks
Truss sends webhooks when payment intents change. Inbound and outbound payment intents use the same events and payload fields; use direction on the payment intent in event_payload to tell invoices from bills.
event_name |
When it fires |
|---|---|
payment_intent.paid |
The payment intent is fully paid (balance_paid equals total). |
payment_intent.canceled |
The payment intent is canceled. |
payment_intent.updated |
Fields such as total, addenda, note, memo, or due_date change. |
payment_intent.transaction.added |
A transaction or external transaction is added to the payment intent (for example when a customer pays an invoice or a company pays a bill). |
These events are sent for payment intents created through the Foundation API and for those created in the Truss dashboard or other Truss channels.
Webhook payloads use the same payment intent fields as list responses: they include wallet_uid and omit transactions, except payment_intent.transaction.added, which includes the new transaction on the payload. checkout_url is omitted from webhook payloads. To reconcile a bill after dashboard payment, handle payment_intent.transaction.added and payment_intent.paid the same way you would for an inbound invoice.
Event schemas are in the API Reference.
Managing Payment Intents Via API
| Operation | Inbound | Outbound |
|---|---|---|
| Create | POST /v1/payment-intents/inbound/ |
POST /v1/payment-intents/outbound/ |
| List | GET /v1/payment-intents/inbound/ |
GET /v1/payment-intents/outbound/ |
| Retrieve | GET /v1/payment-intents/inbound/{uid}/ |
GET /v1/payment-intents/outbound/{uid}/ |
| Update | PATCH /v1/payment-intents/inbound/{uid}/ |
PATCH /v1/payment-intents/outbound/{uid}/ |
| Cancel | POST /v1/payment-intents/inbound/{uid}/cancel/ |
POST /v1/payment-intents/outbound/{uid}/cancel/ |
List responses omit transactions; retrieve a payment intent to see them. See Scopes for the scopes each endpoint requires, and the API References for inbound and outbound payment intents and wallets for request and response details.

