Skip to main content

Flow actions

How to use the seven actions Flourish Payments adds to Flow: charging a saved card, billing with Stripe invoices and subscriptions, and reading what a payment form collected.

Overview​

In Flow Builder, add an Action element and look under the Flourish Payments category.

ActionWhat it's for
Charge Payment TokenCharge a saved card, for recurring payments and back-office charges.
Charge Saved Payment MethodThe same charge, with the card handed to it directly.
Send Stripe InvoiceBill an Opportunity with a Stripe invoice.
Start Stripe SubscriptionStart a recurring subscription for an Opportunity's payer.
Cancel Stripe SubscriptionEnd a subscription, now or after the paid period.
Get Custom Data ValueRead one value a payment form collected.
Filter by Custom DataNarrow a list of Opportunities by a value the form collected.

Charging a saved card​

When a customer ticks the box to save their card at checkout, the package keeps a token for it. The token isn't the card: it's a reference Stripe accepts on your behalf, for that customer, with no one at the keyboard. That's what both charging actions spend.

The token is stored with the rest of the payment history in Stripe Sync on the Opportunity, in this shape:

{
"stripeCustomerId": "cus_...",
"paymentMethodToken": "pm_...",
"paymentMethodStatus": "active"
}

Charge Payment Token​

The action to use for anything recurring. It reads the credential out of a field rather than taking it as an input, which means the token can live in one place and every record that needs it can point at that place.

InputRequiredWhat it takes
Credential JSON FieldYesThe field holding the JSON above. A path through a parent works, so npe03__Recurring_Donation__r.Stripe_Credentials__c reads the token off the parent rather than needing a copy on every child.
Amount FieldYesThe field holding the dollar amount to charge, for example Amount.
Record IDOne of these twoCharge this one record now, and wait for the answer.
SOQL QueryOne of these twoCharge every row this query returns, in the background.
CurrencyNoISO currency code. Defaults to usd.
DescriptionNoA description sent to Stripe with the charge.
Chunk SizeNoHow many charges run per transaction on the background path. Defaults to 50, capped at 90.
OutputWhat it tells you
SuccessThe single charge went through. Only meaningful on the Record ID path.
Payment Intent ID, StatusThe result of that single charge.
EnqueuedThe background run started.
Records QueuedHow many rows it will charge.
Records SkippedHow many rows it refused to charge.
Error MessageWhy the charge failed or was skipped. On the SOQL Query path, each reason a row was skipped, with how many rows it applied to.

Two paths, and they behave differently.

  • Record ID: the charge happens while the Flow waits, so a Screen Flow can tell the person at the desk what happened.
  • SOQL Query: the action hands the work off and returns straight away. A scheduled Flow that charges a month of installments gets Enqueued, a count and the skip reasons, not an outcome per row. Check the records themselves for those.

Pass one query rather than looping records and calling the action per row. The query is what keeps a large run inside Salesforce's limits, and the action charges in chunks, each chunk its own transaction.

Rows it won't charge. The action checks every row before any money moves, whatever your query selected, and skips it with a reason if:

  • The credential isn't usable: the field is empty, the JSON has no token or no customer, or paymentMethodStatus is anything but active.
  • The record has already been paid: it holds a completed, processing or refunded payment. This catches an installment your Flow charged but never closed.
  • The card was used in the last five days: at the checkout that saved it, for any other record, or for another row earlier in the same run. This stops an installment dated on the day the customer paid at checkout from charging them twice. It also spaces out several overdue installments for one donor instead of charging them all at once.

A skipped row is charged by a later run once the reason clears, as long as your query still selects it. So build scheduled queries with a lookback, such as installments due in the last seven days that aren't closed, rather than only those due today. A schedule that charges the same card more often than every five days can't be charged by this action.

Charging twice in one day is guarded against. Each charge carries a key built from the record and the date, and Stripe honors it. If a background run dies partway and is retried the same day, the rows it already charged return their original result instead of charging again.

A successful charge writes a receipt and stops there. It appends the payment to Stripe Sync, recording the card it used, and nothing else. It doesn't set the stage to Closed Won and doesn't mark a payment record paid, because what a recurring charge means for your records is yours to decide. Do it in the same Flow, after the action.

The query is checked before it runs. It has to be a single SELECT with no semicolon, and it must select the credential field and the amount field you named.

Charge Saved Payment Method​

The same charge, with the credentials handed to it directly. Use it when the Flow already has the customer and token in variables, or when the token doesn't live in a field on the record.

InputRequiredWhat it takes
Stripe Customer IDYesThe cus_... customer.
Payment Method IDYesThe pm_... token saved at a previous checkout.
AmountYesDollars, for example 25.00.
OutputWhat it tells you
SuccessWhether the charge went through.
Payment Intent IDStripe's ID for the charge.
StatusWhat Stripe reported.
Error MessageThe decline reason or the error, when Success is false.

This one charges and returns. It has none of Charge Payment Token's checks and writes nothing to the Opportunity, so anything you want recorded, record it in the Flow.


Invoices and subscriptions​

How these behave on your records is on Products, invoices and subscriptions. Each action works on a list of Opportunities in one go, and reports per Opportunity: a Stripe refusal for one doesn't stop the others.

Send Stripe Invoice​

Bills an Opportunity's payer with a Stripe invoice. The Opportunity's products are the lines; with no products, its Amount is one line.

InputRequiredWhat it takes
Opportunity IDYesThe Opportunity to bill.
Days Until DueNoDays the payer has to pay. Defaults to 30.
Email the InvoiceNoWhen true (the default), Stripe emails the invoice and its reminders to the payer. When false, nothing is emailed; share the Invoice URL yourself.
MemoNoA note shown on the invoice.
OutputWhat it tells you
SuccessThe invoice was created.
Invoice ID, Invoice NumberStripe's identifiers for it.
Invoice URLThe page where the payer views and pays the invoice.
Error MessageWhy it wasn't created.

Start Stripe Subscription​

Starts a subscription for the Opportunity's payer, its Contact. Give it a price in one of three ways: a Stripe Price ID; a Product ID, which uses the product's newest recurring price; or a Product ID with an Amount and Billing Interval.

InputRequiredWhat it takes
Opportunity IDYesThe Opportunity the subscription starts from. Its Contact pays.
Stripe Price IDThis or a Product IDA recurring Stripe price, price_....
Product IDThis or a Stripe Price IDA Product sent to Stripe. Uses its newest recurring price, unless an Amount is given.
AmountNoWith a Product ID: dollars charged each interval, in place of the product's price.
Billing IntervalNoWith an Amount: day, week, month (the default) or year.
Interval CountNoWith an Amount: intervals between charges, for example 3 with month for quarterly. Defaults to 1.
QuantityNoUnits of the price charged each interval. Defaults to 1.
Start DateNoA future date for the first charge. Leave blank to charge now.
Bill by Emailed InvoiceNoWhen true, Stripe emails an invoice each period instead of charging a card.
Days Until DueNoWith Bill by Emailed Invoice: days the payer has to pay each invoice. Defaults to 30.
OutputWhat it tells you
SuccessThe subscription started.
Subscription IDStripe's ID for it.
StatusStripe's status for the subscription, for example active or trialing.
First Invoice URLThe page for the first invoice, when one was issued.
Error MessageWhy it didn't start, including a declined card. A refused first payment creates nothing.

Without Bill by Emailed Invoice, the payer is charged on the card saved at the Opportunity's checkout, if there was one, or the default card on their Stripe customer. An Opportunity can have one live subscription at a time; the action refuses a second.

Cancel Stripe Subscription​

InputRequiredWhat it takes
Opportunity IDYesThe Opportunity the subscription started from, or one of its payments.
Cancel ImmediatelyNoWhen true, ends the subscription now. When false (the default), it ends after the period already paid for.
OutputWhat it tells you
SuccessThe change was made.
StatusStripe's status for the subscription after the change.
Error MessageWhy it wasn't made.

Reading what the form collected​

Both of these read Payment Custom Data, where every form field the package doesn't handle itself ends up. See Payments in Salesforce.

Get Custom Data Value​

Pulls one value out by name.

InputRequiredWhat it takes
Key NameYesThe field name from the form. Dot notation reaches nested values, for example pricing.total.
Opportunity IDIf no JSON StringThe Opportunity to read.
JSON StringIf no Opportunity IDThe JSON itself. In a record-triggered Flow, pass $Record.pay_Custom_Data__c and save the query.

The output is Value.

Filter by Custom Data​

Narrows a list of Opportunities to the ones whose custom data matches.

InputRequiredWhat it takes
Opportunity IDsYesComma-delimited list to test.
Key NameYesThe field name, dot notation allowed.
OperatorNoequals (the default), not_equals, contains, not_contains, is_blank, is_not_blank.
Key ValueNoWhat to compare against. Not needed for is_blank and is_not_blank.

The output is Matching IDs, comma-delimited. Comparisons are case-sensitive.