Stripe: Working with other systems

Table of contents
  1. Summary
  2. Anrok integration invoice metadata
  3. Example: Using Stripe API with Anrok integration
    1. Create new invoice
    2. Confirm Anrok has processed the invoice
    3. Update the invoice
    4. Finalize the invoice

Summary

When working with multiple systems on Stripe, it’s important to understand how those systems might interact with each other. These other systems could be your own internal billing system, another Stripe integration, or any other tool that modifies invoices on Stripe.

For Anrok, there are two things to keep in mind:

  • Each time an invoice is modified, Anrok may need to re-calculate and update tax.
  • When an invoice is finalized, it can no longer be modified.

If you’re using another system on Stripe that modifies or finalizes invoices, then those systems are especially important to understand and it may be necessary to communicate with Anrok in some cases to ensure things operate smoothly.

Anrok integration invoice metadata

To help facilitate the use of other systems, the Anrok integration is capable of communicating via invoice metadata. You can think of this metadata like an invoice versioning system.

  • "anrok_user_input" - Versioning string provided by other system.
  • "anrok_user_input_last_seen_by_anrok" - Last versioning string that Anrok has processed.

The diagram and steps below explain how this metadata can be used to communicate with Anrok.

  1. The other system creates or updates an invoice, providing a unique version string in "anrok_user_input".
  2. Anrok processes the invoice, updating tax if necessary, and updates "anrok_user_input_last_seen_by_anrok" to match "anrok_user_input".
  3. The other system reads the metadata, confirms that Anrok has seen latest version, then finalizes the invoice.
    sequenceDiagram
    participant O as Other System
    participant S as Stripe
    participant A as Anrok
    O->>S: create invoice, update metadata
{"anrok_user_input": "v1"} S-->>A: invoice.created webhook A->>S: add tax to invoice, update metadata
{"anrok_user_input_last_seen_by_anrok": "v1"} S-->>O: invoice.updated webhook O->>O: read invoice metadata O->>O: confirm anrok has seen latest version O->>S: finalize invoice S-->>A: invoice.updated webhook A->>A: record tranasction for filing

Example: Using Stripe API with Anrok integration

Let’s look at a specific example. We’re going to do the following:

  1. Create a new invoice with the Stripe API, supplying the Anrok versioning metadata.
  2. Confirm that Anrok has processed the invoice by inspecting the metadata.
  3. Update the invoice, supplying a new version number.
  4. Confirm that Anrok has processed the latest version of the invoice.
  5. Finalize the invoice and collect payment.

Create new invoice

First, we’ll create the invoice item that we’d like to invoice to the customer. In this example, we’re creating one invoice item for $10.

stripe_api_key='sk_xxx'
curl https://api.stripe.com/v1/invoiceitems \
  -u $stripe_api_key: \
  -d 'customer'='cus_xxx' \
  -d 'price_data[currency]'='usd' \
  -d 'price_data[product]'='prod_xxx' \
  -d 'price_data[unit_amount]'='1000'

Next, we’ll create a new invoice for the same customer.

  • pending_invoice_items_behavior: true - This tells Stripe to add the invoice item we created in the previous step to this invoice.
  • auto_advance: false - This tells Stripe to keep the invoice in a draft state so we (and Anrok) can edit it.
  • metadata[anrok_user_input]=v1 - This is the version number for the invoice. We’re using “v1” in this example, but any unique string will work.
invoice_version='v1'
curl https://api.stripe.com/v1/invoices \
  -u $stripe_api_key: \
  -d 'customer'='cus_xxx' \
  -d 'pending_invoice_items_behavior'='include' \
  -d 'auto_advance'='false' \
  -d 'metadata[anrok_user_input]'=$invoice_version

Confirm Anrok has processed the invoice

Now that our invoice has been created and is sitting in a draft state, Anrok has been notified of the new invoice and has added tax, if necessary. To confirm that Anrok has seen the invoice, we can fetch the invoice and look at the metadata.

Notice that anrok_user_input is now equal to anrok_user_input_last_seen_by_anrok. This tells us that Anrok has processed the invoice.

Anrok adds some additional useful metadata as well, but we can ignore those for now and they’ll be reviewed later.

invoice_id=in_xxx
curl https://api.stripe.com/v1/invoices/$invoice_id \
  -u $stripe_api_key: \
  | jq '.metadata'

{
  "anrok_last_processing_time": "2024-01-17T18:48:40.016Z",
  "anrok_processing_was_successful": "true",
  "anrok_user_input": "v1",
  "anrok_user_input_last_seen_by_anrok": "v1"
}

Update the invoice

The invoice is now in a state where we could finalize it and send it to the customer, but first let’s review how to update an invoice.

In the example below, we’re changing the price of our line item from $10 to $5, then we’re updating the invoice with a new version string using anrok_user_input. We could use “v2” as the version string, but instead we’re going to use a timestamp. Again, any unique string will work as the version string.

invoice_line_id=il_xxx
curl https://api.stripe.com/v1/invoices/$invoice_id/lines/$invoice_line_id \
  -u $stripe_api_key: \
  -d 'price_data[currency]'='usd' \
  -d 'price_data[product]'='prod_xxx' \
  -d 'price_data[unit_amount]'='500'

invoice_version=$(gdate +%s.%N)
curl https://api.stripe.com/v1/invoices/$invoice_id \
  -u $stripe_api_key: \
  -d 'metadata[anrok_user_input]'=$invoice_version

Finalize the invoice

We can again confirm that Anrok has processed the latest version of the invoice by fetching the invoice and comparing anrok_user_input with anrok_user_input_last_seen_by_anrok.

curl https://api.stripe.com/v1/invoices/$invoice_id \
  -u $stripe_api_key: \
  | jq '.metadata'

{
  "anrok_last_processing_time": "2024-01-17T19:10:32.330Z",
  "anrok_processing_was_successful": "true",
  "anrok_user_input": "1705518629.789870000",
  "anrok_user_input_last_seen_by_anrok": "1705518629.789870000"
}

Once we’ve confirmed the invoice has been processed, we can finalize the invoice and send to the customer (or collect payment).

curl -X POST https://api.stripe.com/v1/invoices/$invoice_id/finalize \
  -u $stripe_api_key: \
  -d 'auto_advance':'true'