`trigger` with customizable data
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:
- A charge creation request with
captured=false, to create a new uncaptured charge object - 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!
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 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.
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 The command to run a custom fixtures file is fixtures, not trigger:
$ stripe fixtures my_fixture.json
We need to document this better :)
Awesome! thanks for all the help :)
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..
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?
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 ""
Same here.
Same
@TuureKaunisto @aragalie @LionelBergen Sorry about that! The issue should be fixed in v1.3.4.
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
}
}
}
]
}
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.
How can I set the API's version for my fixtures (via CLI or in the fxiture) ?
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 ✌🏻
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';
}
stripe trigger customer.subscription.created --add customer:[email protected] seems to work 👍
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.