Stripe CLI trigger payment intent with specific id

Viewed 2032

I am using Stripe in my application and I use the payment intent id also as the identifier to store my customer order details. I wrote a webhook endpoint in order to change customer order status and I would like to test locally first.

How can I trigger payment_intent.succeeded event with a specific payment_intent id so that I can find my customer order from the database?

4 Answers

There's no way to trigger it with a specific Payment Intent like that; what you'll want to do instead is use the CLI's forwarding, but go through your flow to actually create a test payment. That will result in a payment_intent.succeeded event for an expected/known Payment Intent.

I had a similar problem whereby I wanted to test a failed subscription payment. Looking into the Stripe CLI fixtures, I took the default json they use and created the following script.

/* eslint-disable @typescript-eslint/no-var-requires */
const { exec } = require('child_process')
const fs = require('fs')
const path = require('path')

const args = process.argv.slice(2)

if (args[0] !== '-customer') {
  console.log('-customer argument missing')
  process.exit(22)
}

if (args[1] === undefined) {
  console.log('customer id required')
  process.exit(22)
}

const failedInvoiceJson = {
  _meta: {
    template_version: 0
  },
  fixtures: [
    {
      name: 'invoiceitem',
      path: '/v1/invoiceitems',
      method: 'post',
      params: {
        amount: 2000,
        currency: 'usd',
        customer: `${args[1]}`,
        description: '(created by Stripe CLI)'
      }
    },
    {
      name: 'invoice',
      path: '/v1/invoices',
      method: 'post',
      params: {
        customer: `${args[1]}`,
        description: '(created by Stripe CLI)'
      }
    },
    {
      name: 'invoice_pay',
      path: '/v1/invoices/${invoice:id}/pay',
      method: 'post'
    }
  ]
}

fs.writeFileSync(
  path.join(process.cwd(), './test/failedInvoice.json'),
  JSON.stringify(failedInvoiceJson)
)

exec('stripe fixtures test/failedInvoice.json', (error, stdout, stderr) => {
  console.log(`stdout: ${stdout}`)

  fs.unlinkSync(path.join(process.cwd(), './test/failedInvoice.json'))

  if (error) {
    console.log(`error: ${error.message}`)
    return
  }
  if (stderr) {
    console.log(`stderr: ${stderr}`)
    return
  }
})

With this script I'm able to run the command node test/failedInvoice.ts -customer xxx where xxx is the ID of an existing stripe user in my database.

When the payment is succeeded on the payment page, write an UPDATE query to change the status of the order.

To do this, you need to store the order_id while creating the Payment Intent. Use metadata field.

\Stripe\PaymentIntent::create([
    'amount' => 1099,
    'currency' => 'usd',
    'payment_method_types' => ['card'],
    'metadata' => [
        'order_id' => '6735',
    ],
]);

Retrieve the order_id from the Payment Intent when the payment is succeeded to update the status of the order.

Take a template from the repository and change a variable like ${invoice:id} to use an environment variable, i.e. ${.env:INVOICE_ID}. Then, you can call INVOICE_ID=10 stripe fixtures yourfile.json.

Related