stripe-cli icon indicating copy to clipboard operation
stripe-cli copied to clipboard

`trigger` with customizable data

Open ob-stripe opened this issue 6 years ago • 18 comments

Description of the desired feature

The trigger command can be used to create sample events of various types. Many users would like to be customize the events.

For example, one could trigger a charge.captured event for an existing charge object:

$ stripe trigger charge.captured --charge ch_123

Or one could trigger a customer.subscription.created for a specific customer, with custom metadata going into the subscription object:

$ stripe trigger customer.subscription.created --customer cus_123 -d metadata[key]=value

At the moment, none of the above is possible.

Current implementation of the trigger command

Under the hood, the trigger command works by sending a series of API requests. E.g. to trigger a charge.captured event, the CLI will send two requests to Stripe:

  1. A charge creation request with captured=false, to create a new uncaptured charge object
  2. A charge capture request for the newly created object

These series of API requests are defined using as JSON files ("fixtures" files) that are embedded in the executable, e.g. https://github.com/stripe/stripe-cli/blob/master/triggers/charge.captured.json.

Difficulties in providing a generic interface to customize data

Due to the large number of possible event types and scenarios, it's not feasible to customize the behavior of the CLI per event type -- that would be near impossible to maintain in the long term. We want to keep the interface of the trigger command generic. However, because each "trigger" is defined as an arbitrary sequence of API requests, it is difficult to provide a generic CLI interface to customize the data that goes into each request.

For instance, for the case of capturing an existing charge object, the trigger command would have to omit the first request (the charge creation request) when the --charge flag is provided.

For the case of providing custom metadata when creating a subscription, it's even more complicated: under the hood, the trigger command needs to create a new customer and a new plan before it can create the new subscription. If custom metadata is provided on the command line, it's not clear which resource (the plan, the customer or the subscription) should receive the custom metadata.

Creating your own fixtures files

It's not a perfect solution, but you can create your own fixtures files (i.e. sequences of API requests) with your own custom data and have the CLI play them with the stripe fixtures command.

E.g. in order to capture an existing charge object, you could create a my_fixture.json file with the following contents:

{
  "_meta": {
    "template_version": 0
  },
  "fixtures": [
    {
      "name": "capture",
      "path": "/v1/charges/ch_123/capture",
      "method": "post"
    }
  ]
}

then play it with stripe fixtures my_fixture.json. This would send a single request to capture the ch_123 charge.

You can take a look at the various existing fixtures in https://github.com/stripe/stripe-cli/tree/master/triggers and use them as templates to write your own files.

In the future, we will clearly document the syntax of the fixtures files.

Feedback

We realize having to write your own fixtures files is more cumbersome than a single command line invocation, and are looking into ways of improving the experience here. Please feel free to reply with this issue with feedback or suggestions!

ob-stripe avatar Nov 06 '19 18:11 ob-stripe

Thanks for the detailed explanation.

Having the fixture files is a great compromise right now for those more complicated requests. In most cases, what I'm trying to accomplish is to trigger a series of boilerplate events from some known starting point.

For example: say I've already connected a standard account in test mode. I'd like to be able to trigger a series of events like customer.subscription.created (with specific metadata) -> ... -> invoice.payment.succeeded (from the subscription just created) without providing all the details in the .... I still want to be able to receive the events that happen in the ... though, such as customer.subscription.updated.

It seems it may be possible to start from a fixture that you've provided (like for invoice.payment.succeeded) and add the customization to the specific step where I need it. From here the following steps will inherit the correct details as they would in real requests. Is that the case?

kypalmer avatar Nov 07 '19 05:11 kypalmer

@kypalmer Yes, that sounds correct. For the specific case of Connect, I think right now the CLI lacks the ability to execute fixtures files on connected accounts, but we can look into adding support for that -- I don't think that should be too hard.

ob-stripe avatar Nov 07 '19 05:11 ob-stripe

Nice! Connected account support would be awesome.

Downloaded the source and ran a build with go after creating a copy and modifying of one of the fixtures. I tried running it and got this:

stripe-cli-1.2.0 ~ ./stripe trigger customer.subscription.created_customized
=> event customer.subscription.created_customized is not supported

Any Idea how I can run this? (I named the file customer.subscription.created_customized.json in the fixtures/ directory.

Edit: Just tested my modification without renaming the file (using customer.subscription.created.json), and it worked. So it seems the filename is the only hangup. Do you know where the list of 'allowed triggers' is?

Thanks

kypalmer avatar Nov 07 '19 06:11 kypalmer

@kypalmer The command to run a custom fixtures file is fixtures, not trigger:

$ stripe fixtures my_fixture.json

We need to document this better :)

ob-stripe avatar Nov 07 '19 06:11 ob-stripe

Awesome! thanks for all the help :)

kypalmer avatar Nov 07 '19 06:11 kypalmer

It would be great if we could "Generate fixtures from defaults". Right now its hard to know the api and I want and example of each fixture but I don'w know how to access them.

The desirable workflow for me would be to edit from a template and remove what I don't need.

Think of it as fixture code gen..

shortcircuit3 avatar Jan 06 '20 21:01 shortcircuit3

What I'm bit missing is a way when any of fixture is run to get id of created data. Is that even possible with fixtures?

creaux avatar Feb 05 '20 19:02 creaux

I get the following error when I try to play an existing fixture:

stripe fixtures backend/fixtures/payment-intent-fixture.json
Setting up fixture for: payment_intent
Post /v1/payment_intents: unsupported protocol scheme ""

TuureKaunisto avatar Feb 06 '20 09:02 TuureKaunisto

Same here.

aragalie avatar Feb 12 '20 19:02 aragalie

Same

LionelBergen avatar Feb 15 '20 07:02 LionelBergen

@TuureKaunisto @aragalie @LionelBergen Sorry about that! The issue should be fixed in v1.3.4.

ob-stripe avatar Feb 16 '20 06:02 ob-stripe

Hi everyone, just wanted to say a quick thank you for doing a nice job with the stripe cli in Version 1.3.5! I had the same error "unsupported protocol scheme. But the new release works good for me here. I'm now able to trigger my own events with metadata.

This is my current workflow for reference:

$ stripe listen --forward-to http://localhost:5000/stripe
$ stripe fixtures customer.created.meta.json

I copied the existing fixture from https://github.com/stripe/stripe-cli/tree/master/triggers and added my metadata for a new "customer.created.meta.json".

{
  "_meta": {
    "template_version": 0
  },
  "fixtures": [
    {
      "name": "customer",
      "path": "/v1/customers",
      "method": "post",
      "params": {
        "description": "(created by Stripe CLI) with meta",
        "metadata": {
            "user_id": 31
        }
      }
    }
  ]
}

chriso0710 avatar Feb 29 '20 10:02 chriso0710

How about having a separate repository with fixtures for a variety of workflows? That way the community can request and contribute fixtures for their most common workflows.

I guess we could potentially use our OpenAPI spec to generate fixtures for every single API request, but I wonder if there is more value in specific workflows that outline a chain of requests.

thorsten-stripe avatar Mar 13 '20 10:03 thorsten-stripe

How can I set the API's version for my fixtures (via CLI or in the fxiture) ?

ilan-schemoul avatar Mar 26 '20 02:03 ilan-schemoul

I confirmed this is still working, although the link in the OP to the fixture templates seems to be broken (this one).

I think I found the fixture templates here: https://github.com/stripe/stripe-cli/tree/master/pkg/fixtures/triggers.

I hope this saves someone else a couple of minutes ✌🏻

Culpable avatar Mar 17 '21 01:03 Culpable

Any updates?

I would like to be able to do stripe trigger customer.created --email="[email protected]" (because the default customer has no email address.

Or stripe trigger customer.subscription.created --customer.email="[email protected]"

EDIT:

In my case, a quick solution was to set a default email in my webhook handler (PHP) instead of the CLI request, pretty hacky but works fine for my app:

        $email = $customer->email;
        if(!$email && $customer->description == '(created by Stripe CLI)') {
            $email = generateSecureToken(10, 'chars') . '@mail.com';
        }

Cristy94 avatar Feb 08 '22 13:02 Cristy94

stripe trigger customer.subscription.created --add customer:[email protected] seems to work 👍

jamesckemp avatar Nov 18 '22 09:11 jamesckemp

Is it possible to trigger events for existing customers?

stripe trigger customer.subscription.deleted --add customer:id=cus_XXX

I get a "resource_already_exists" error.

asad-c avatar Apr 05 '23 21:04 asad-c