Question Types

Payment

The payment question type lets you collect a payment from the user. This is a bit more involved than most other question types and involves some setup.

Setup

Once you've created a form, look for the Payments provider section, and click on Connect payments:

You'll be redirected to a Stripe login/registration form.

Once you've signed up/logged in, your form will be linked to your Stripe account, enabling you to receive payments.

Requesting a Payment

Here's a simple example (all options are documented further down):

await form.payment('Thanks for your interest! You can make the purchase below:', {
  currency: 'usd',
  items: [{
    amount: 3000, // This uses the specified currency's smallest unit (in this case, cents)
    name: 'Aperture Science Handheld Portal Device', 
    quantity: 1
  }]
});

Which generates a question that looks like this:

When the user clicks on Pay, the payment page opens in a new tab:

A completed payment will show up in your Stripe dashboard.

If this is your first time using Stripe, you may have to apply branding settings to your account before payment() works correctly.

Fees

Payments are subject to Stripe's fees. Formulate doesn't charge any additional fees at this time.

Return Value

payment() returns a PaymentStatus object that contains these keys, which you can use later in your script:

Key Type
status string One of: successful, stripe-not-set-up, and failed
id string Stripe identifier for the payment (only set when status is successful)
let {status, id} = await form.payment('Thanks for your interest! You can make the purchase below:', {
  currency: 'usd',
  items: [{
    amount: 3000, // This uses the specified currency's smallest unit (in this case, cents)
    name: 'Aperture Science Handheld Portal Device', 
    quantity: 1
  }]
});

if (status === 'successful') {
  await form.statement("We'll send you a confirmation shortly via email");
}
if (status === 'failed') {
  await form.statement("Oops, looks like the payment didn't go through.");
}

Using the answer from one question within the text of a subsequent question is a special case that requires a tiny bit of extra care. More details on the Interpolation page.

Options

Here's a list of all payment-specific options:

Option Type
currency string A three-letter currency code from https://stripe.com/docs/currencies
items array An array of PaymentLineItem objects

Where each PaymentLineItem object contains the keys:

Key Type
amount number The amount to charge, in cents
name string The product’s name, meant to be displayable to the customer
description string The product’s description, meant to be displayable to the customer
quantity number The quantity of the line item being purchased
imageUrls array A list of up to 8 URLs of images for this product, meant to be displayable to the customer

You can also pass global options, which are valid for all question types.