30 KiB
Stripe API
- Product
- Customer
- One-Time Invoicing
- One-Time Invoicing (Payment method first)
- Subscriptions
- A Unified Purchasing Experience
- Product
- Customer
- One-Time Invoicing
- One-Time Invoicing (Payment method first)
- Subscriptions
- A Unified Purchasing Experience
Product
stripe products create \
--stripe-account=$account \
--name="Example Product (Org-Roam Doc)" \
-d "images[0]"="https://www.orgroam.com/img/logo.png" \
| jq -r .id
prod_JBeWfGHNqBcy5B
Non-Recurring Price
stripe prices create \
--stripe-account=$account \
--product=$product \
--unit-amount=-1 \
--currency=jpy \
-d "nickname"="Non-Recurring"
{ "error": { "message": "This value must be less than or equal to 999999999999 (it currently is '9999999999991').", "param": "unit_amount", "type": "invalid_request_error" } }
Recurring Price
stripe prices create \
--stripe-account=$account \
--product=$product \
--unit-amount=999 \
--currency=usd \
-d "nickname"="Recurring" \
-d "recurring[interval]"="month" \
| jq -r .id
price_1IZHFZIoFf3wvXpRtHW5EKFo
Customer
stripe customers create \
--stripe-account=$account \
--description="Org Roam Docs Customer" \
--name="Correl Roush" \
--email="correl+stripe.roam.docs@gmail.com" \
| jq -r .id
cus_JBeXOsWSmfXrDX
One-Time Invoicing
We set up a purchase for the client to then complete by confirming the payment intent with payment information.
Create invoice item
stripe invoiceitems create \
--stripe-account=$account \
--customer=$customer \
--price=$price \
| jq -r .id
ii_1IZHGHIoFf3wvXpRnP7xBsbd
Create invoice
stripe invoices create \
--stripe-account="$account" \
--customer="$customer" \
| jq -r .id
in_1IZHGOIoFf3wvXpRuP2Og77y
stripe invoices finalize_invoice \
--stripe-account=$account \
$invoice
{ "id": "in_1IZHGOIoFf3wvXpRuP2Og77y", "object": "invoice", "account_country": "US", "account_name": "Correl's Stuff", "account_tax_ids": null, "amount_due": 350, "amount_paid": 0, "amount_remaining": 350, "application_fee_amount": null, "attempt_count": 0, "attempted": false, "auto_advance": false, "billing_reason": "manual", "charge": null, "collection_method": "charge_automatically", "created": 1616771272, "currency": "usd", "custom_fields": null, "customer": "cus_JBeXOsWSmfXrDX", "customer_address": null, "customer_email": "correl+stripe.roam.docs@gmail.com", "customer_name": "Correl Roush", "customer_phone": null, "customer_shipping": null, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "description": null, "discount": null, "discounts": [ ], "due_date": null, "ending_balance": 0, "footer": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1IGnMkIoFf3wvXpR/invst_JBeZpwIUNWNhG3JLRP5QBZ2RpKeDs8t", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1IGnMkIoFf3wvXpR/invst_JBeZpwIUNWNhG3JLRP5QBZ2RpKeDs8t/pdf", "last_finalization_error": null, "lines": { "object": "list", "data": [ { "id": "il_1IZHGHIoFf3wvXpRMwwv5nhW", "object": "line_item", "amount": 350, "currency": "usd", "description": "Example Product (Org-Roam Doc)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice_item": "ii_1IZHGHIoFf3wvXpRnP7xBsbd", "livemode": false, "metadata": { }, "period": { "end": 1616771265, "start": 1616771265 }, "plan": null, "price": { "id": "price_1IZHFSIoFf3wvXpRHwH3GRm8", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1616771214, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": "Non-Recurring", "product": "prod_JBeWfGHNqBcy5B", "recurring": null, "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 350, "unit_amount_decimal": "350" }, "proration": false, "quantity": 1, "subscription": null, "tax_amounts": [ ], "tax_rates": [ ], "type": "invoiceitem" } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1IZHGOIoFf3wvXpRuP2Og77y/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "0EBAE885-0001", "on_behalf_of": null, "paid": false, "payment_intent": "pi_1IZHH8IoFf3wvXpRKYVCxVtO", "payment_settings": { "payment_method_options": null, "payment_method_types": null }, "period_end": 1616771272, "period_start": 1616771272, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "open", "status_transitions": { "finalized_at": 1616771318, "marked_uncollectible_at": null, "paid_at": null, "voided_at": null }, "subscription": null, "subtotal": 350, "tax": null, "total": 350, "total_discount_amounts": [ ], "total_tax_amounts": [ ], "transfer_data": null, "webhooks_delivered_at": 1616771274 }
Pay the invoice
stripe payment_intents confirm $intent \
--payment-method=pm_card_visa
{ "id": "pi_1IZG0gIoFf3wvXpRMv4JIJlv", "object": "payment_intent", "amount": 350, "amount_capturable": 0, "amount_received": 350, "application": null, "application_fee_amount": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ { "id": "ch_1IZG1rIoFf3wvXpRVFw1lFw7", "object": "charge", "amount": 350, "amount_captured": 350, "amount_refunded": 0, "application": null, "application_fee": null, "application_fee_amount": null, "balance_transaction": "txn_1IZG1rIoFf3wvXpR7ROwaORh", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "calculated_statement_descriptor": "CORRELS STUFF", "captured": true, "created": 1616766527, "currency": "usd", "customer": "cus_JBNQ85gmNWdWB3", "description": "Payment for Invoice", "destination": null, "dispute": null, "disputed": false, "failure_code": null, "failure_message": null, "fraud_details": { }, "invoice": "in_1IZG0YIoFf3wvXpR6aGs4GtD", "livemode": false, "metadata": { }, "on_behalf_of": null, "order": null, "outcome": { "network_status": "approved_by_network", "reason": null, "risk_level": "normal", "risk_score": 39, "seller_message": "Payment complete.", "type": "authorized" }, "paid": true, "payment_intent": "pi_1IZG0gIoFf3wvXpRMv4JIJlv", "payment_method": "pm_1IZG1qIoFf3wvXpRX3NUaXbF", "payment_method_details": { "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": null }, "country": "US", "exp_month": 3, "exp_year": 2022, "fingerprint": "ueUYSX2U2UUDmYpO", "funding": "credit", "installments": null, "last4": "4242", "network": "visa", "three_d_secure": null, "wallet": null }, "type": "card" }, "receipt_email": null, "receipt_number": null, "receipt_url": "https://pay.stripe.com/receipts/acct_1IGnMkIoFf3wvXpR/ch_1IZG1rIoFf3wvXpRVFw1lFw7/rcpt_JBdIhBejsEXLYLJMLjteIt8UWMMh5md", "refunded": false, "refunds": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges/ch_1IZG1rIoFf3wvXpRVFw1lFw7/refunds" }, "review": null, "shipping": null, "source": null, "source_transfer": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null } ], "has_more": false, "total_count": 1, "url": "/v1/charges?payment_intent=pi_1IZG0gIoFf3wvXpRMv4JIJlv" }, "client_secret": "pi_1IZG0gIoFf3wvXpRMv4JIJlv_secret_48XYkW8i6bDhBOtA7AE6R9drd", "confirmation_method": "automatic", "created": 1616766454, "currency": "usd", "customer": "cus_JBNQ85gmNWdWB3", "description": "Payment for Invoice", "invoice": "in_1IZG0YIoFf3wvXpR6aGs4GtD", "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1IZG1qIoFf3wvXpRX3NUaXbF", "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null }
One-Time Invoicing (Payment method first)
By having the client prepare the payment intent before requesting the purchase, we can handle invoicing and completing the purchase on our end without further input from the client.
Create a payment method
stripe payment_methods create \
--stripe-account=$account \
--type=card \
-d "card[number]"=4242424242424242 \
-d "card[exp_month]"=3 \
-d "card[exp_year]"=2022 \
-d "card[cvc]"=314 \
| jq -r '.id'
pm_1J5FujIoFf3wvXpRgemyYO93
Attach the payment method to the customer
stripe payment_methods attach "$payment_method" \
--stripe-account=$account \
--customer="$customer"
{ "id": "pm_1IZHILIoFf3wvXpR3oRjPoMx", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 3, "exp_year": 2022, "fingerprint": "C5qD8oSCGvVCbtcH", "funding": "credit", "generated_from": null, "last4": "4242", "networks": { "available": [ "visa" ], "preferred": null }, "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1616771394, "customer": "cus_JBeXOsWSmfXrDX", "livemode": false, "metadata": { }, "type": "card" }
Create invoice item
stripe invoiceitems create \
--stripe-account=$account \
--customer=$customer \
--price=$price \
| jq -r .id
ii_1IZJF0IoFf3wvXpROwCaDRo0
Create invoice
stripe invoices create \
--stripe-account="$account" \
--customer="$customer" \
--auto-advance=false \
-d "application_fee_amount"=35 \
-d "default_payment_method"=$payment_method \
| jq -r .id
in_1IZJF5IoFf3wvXpRu9PnTZIl
Pay Invoice
stripe invoices pay \
--stripe-account=$account \
$invoice
{ "id": "in_1IZJF5IoFf3wvXpRu9PnTZIl", "object": "invoice", "account_country": "US", "account_name": "Correl's Stuff", "account_tax_ids": null, "amount_due": 350, "amount_paid": 350, "amount_remaining": 0, "application_fee_amount": 35, "attempt_count": 1, "attempted": true, "auto_advance": false, "billing_reason": "manual", "charge": "ch_1IZJFdIoFf3wvXpRfCT89Njs", "collection_method": "charge_automatically", "created": 1616778879, "currency": "usd", "custom_fields": null, "customer": "cus_JBeXOsWSmfXrDX", "customer_address": null, "customer_email": "correl+stripe.roam.docs@gmail.com", "customer_name": "Correl Roush", "customer_phone": null, "customer_shipping": null, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": "pm_1IZHILIoFf3wvXpR3oRjPoMx", "default_source": null, "default_tax_rates": [ ], "description": null, "discount": null, "discounts": [ ], "due_date": null, "ending_balance": 0, "footer": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1IGnMkIoFf3wvXpR/invst_JBgcIFGvkWp3ZnI1HxNWwAZl7ccRzbY", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1IGnMkIoFf3wvXpR/invst_JBgcIFGvkWp3ZnI1HxNWwAZl7ccRzbY/pdf", "last_finalization_error": null, "lines": { "object": "list", "data": [ { "id": "il_1IZJF0IoFf3wvXpRdhrY6NFl", "object": "line_item", "amount": 350, "currency": "usd", "description": "Example Product (Org-Roam Doc)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice_item": "ii_1IZJF0IoFf3wvXpROwCaDRo0", "livemode": false, "metadata": { }, "period": { "end": 1616778874, "start": 1616778874 }, "plan": null, "price": { "id": "price_1IZHFSIoFf3wvXpRHwH3GRm8", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1616771214, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": "Non-Recurring", "product": "prod_JBeWfGHNqBcy5B", "recurring": null, "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 350, "unit_amount_decimal": "350" }, "proration": false, "quantity": 1, "subscription": null, "tax_amounts": [ ], "tax_rates": [ ], "type": "invoiceitem" } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1IZJF5IoFf3wvXpRu9PnTZIl/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "0EBAE885-0013", "on_behalf_of": null, "paid": true, "payment_intent": "pi_1IZJFcIoFf3wvXpR60FJfbvD", "payment_settings": { "payment_method_options": null, "payment_method_types": null }, "period_end": 1619449837, "period_start": 1616771437, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "paid", "status_transitions": { "finalized_at": 1616778912, "marked_uncollectible_at": null, "paid_at": 1616778912, "voided_at": null }, "subscription": null, "subtotal": 350, "tax": null, "total": 350, "total_discount_amounts": [ ], "total_tax_amounts": [ ], "transfer_data": null, "webhooks_delivered_at": 1616778880 }
Error handling
- Bad payment methods will fail to attach to the customer, stopping the purchase flow before we attempt to set up the invoice.
- Failure to create an invoice leaves the invoice item on the customer. Because we do not re-use customers, this will not be invoiced and charged.
- Invoice creation leaves the invoice in a draft state, from which it will not progress without an action being taken.
- Payment failure results in the invoice being in a failed state, and it will not retry payment.
- Customer can be cleaned up at any point, which will clean up all data pertaining to it (invoice items, draft / failed invoices).
Attempting to attach a test payment method to a live customer
stripe payment_methods attach "$payment_method" \
--live -p correl \
--customer="$customer"
{ "error": { "code": "resource_missing", "doc_url": "https://stripe.com/docs/error-codes/resource-missing", "message": "No such paymentmethod: 'pm_1J5FujIoFf3wvXpRgemyYO93'; a similar object exists in test mode, but a live mode key was used to make this request.", "param": "payment_method", "type": "invalid_request_error" } }
Subscriptions
Subscriptions require that a customer and payment method are already available. This means we'll need to have the client prepare a payment method, then pass that to us to be attached to the customer we create. We'll then be able to build the subscription, and the payment will be processed by Stripe.
Create a payment method
stripe payment_methods create \
--stripe-account=$account \
--type=card \
-d "card[number]"=4242424242424242 \
-d "card[exp_month]"=3 \
-d "card[exp_year]"=2022 \
-d "card[cvc]"=314 \
| jq -r '.id'
pm_1IZHILIoFf3wvXpR3oRjPoMx
Attach the payment method to the customer
stripe payment_methods attach "$payment_method" \
--stripe-account=$account \
--customer="$customer"
{ "id": "pm_1IZHILIoFf3wvXpR3oRjPoMx", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 3, "exp_year": 2022, "fingerprint": "C5qD8oSCGvVCbtcH", "funding": "credit", "generated_from": null, "last4": "4242", "networks": { "available": [ "visa" ], "preferred": null }, "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1616771394, "customer": "cus_JBeXOsWSmfXrDX", "livemode": false, "metadata": { }, "type": "card" }
Set the payment method as the default
stripe customers update "$customer" \
--stripe-account=$account \
-d "invoice_settings[default_payment_method]=$payment_method"
{ "id": "cus_JBeXOsWSmfXrDX", "object": "customer", "address": null, "balance": 0, "created": 1616771128, "currency": "usd", "default_source": null, "delinquent": false, "description": "Org Roam Docs Customer", "discount": null, "email": "correl+stripe.roam.docs@gmail.com", "invoice_prefix": "0EBAE885", "invoice_settings": { "custom_fields": null, "default_payment_method": "pm_1IZHILIoFf3wvXpR3oRjPoMx", "footer": null }, "livemode": false, "metadata": { }, "name": "Correl Roush", "next_invoice_sequence": 2, "phone": null, "preferred_locales": [ ], "shipping": null, "tax_exempt": "none" }
Create subscription
stripe subscriptions create \
--stripe-account=$account \
--customer="$customer" \
-d "items[0][price]"=$price
{ "id": "sub_JBec2LL8kvDiPi", "object": "subscription", "application_fee_percent": null, "billing_cycle_anchor": 1616771437, "billing_thresholds": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "collection_method": "charge_automatically", "created": 1616771437, "current_period_end": 1619449837, "current_period_start": 1616771437, "customer": "cus_JBeXOsWSmfXrDX", "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "discount": null, "ended_at": null, "items": { "object": "list", "data": [ { "id": "si_JBecQCXkjKpi2j", "object": "subscription_item", "billing_thresholds": null, "created": 1616771438, "metadata": { }, "plan": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "plan", "active": true, "aggregate_usage": null, "amount": 999, "amount_decimal": "999", "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "recurring": { "aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 999, "unit_amount_decimal": "999" }, "quantity": 1, "subscription": "sub_JBec2LL8kvDiPi", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JBec2LL8kvDiPi" }, "latest_invoice": "in_1IZHJ3IoFf3wvXpR6u3Yylyu", "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "plan", "active": true, "aggregate_usage": null, "amount": 999, "amount_decimal": "999", "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start_date": 1616771437, "status": "active", "transfer_data": null, "trial_end": null, "trial_start": null }
Failure cases
Stripe provides a set of credit card numbers for eliciting various responses from their API.
Charge failure
payment_method=$(stripe payment_methods create \
--stripe-account=$account \
--type=card \
-d "card[number]"=4000000000000341 \
-d "card[exp_month]"=3 \
-d "card[exp_year]"=2022 \
-d "card[cvc]"=314 \
| jq -r '.id')
stripe payment_methods attach "$payment_method" \
--stripe-account=$account \
--customer="$customer" \
>/dev/null
# stripe customers update "$customer" \
# --stripe-account=$account \
# -d "invoice_settings[default_payment_method]=$payment_method" >/dev/null
stripe subscriptions create \
--stripe-account=$account \
--customer="$customer" \
-d "default_payment_method"=$payment_method \
-d "items[0][price]"=$price
{ "id": "sub_JgoaKuIlHIVW7l", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "enabled": false }, "billing_cycle_anchor": 1623958380, "billing_thresholds": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "collection_method": "charge_automatically", "created": 1623958380, "current_period_end": 1626550380, "current_period_start": 1623958380, "customer": "cus_JBeXOsWSmfXrDX", "days_until_due": null, "default_payment_method": "pm_1J3QxSIoFf3wvXpRCCwKw9Cj", "default_source": null, "default_tax_rates": [ ], "discount": null, "ended_at": null, "items": { "object": "list", "data": [ { "id": "si_Jgoa4zrlQvwRbA", "object": "subscription_item", "billing_thresholds": null, "created": 1623958381, "metadata": { }, "plan": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "plan", "active": true, "aggregate_usage": null, "amount": 999, "amount_decimal": "999", "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "recurring": { "aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 999, "unit_amount_decimal": "999" }, "quantity": 1, "subscription": "sub_JgoaKuIlHIVW7l", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JgoaKuIlHIVW7l" }, "latest_invoice": "in_1J3QxUIoFf3wvXpRyWAuAxGq", "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1IZHFZIoFf3wvXpRtHW5EKFo", "object": "plan", "active": true, "aggregate_usage": null, "amount": 999, "amount_decimal": "999", "billing_scheme": "per_unit", "created": 1616771221, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": "Recurring", "product": "prod_JBeWfGHNqBcy5B", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start_date": 1623958380, "status": "incomplete", "transfer_data": null, "trial_end": null, "trial_start": null }
A Unified Purchasing Experience
Both /correlr/roam/src/commit/9feb79a9540a97b8ae3316857481190b2a47994a/aweber/One-Time%20Invoicing%20%28Payment%20method%20first%29 and /correlr/roam/src/commit/9feb79a9540a97b8ae3316857481190b2a47994a/aweber/Subscriptions require a payment intent be prepared by the client and to be provided to our backend along with customer information.