Reputation: 8968
I'm following the documentation for Stripe Checkout with server integration: https://stripe.com/docs/payments/checkout/server
The code in the examples works fine, but the problem I'm having is being unable to track the user, or their order, when a purchase is complete.
I have a webhook setup that Stripe pings when a payment is complete. But the response session from Stripe contains no information about the product ordered except for it's name, description, and image. I could use the product name to query the database but I'd much rather an ID, or a slug, of sorts.
$app->post("/stripe-pingback", function(Request $request, Response $response, array $args) {
\Stripe\Stripe::setApiKey("xxxxx");
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'xxxxx';
$payload = $request->getBody();
$sig_header = isset($_SERVER['HTTP_STRIPE_SIGNATURE']) ? $_SERVER['HTTP_STRIPE_SIGNATURE'] : null;
$event = null;
try {
$event = \Stripe\Webhook::constructEvent($payload, $sig_header, $endpoint_secret);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
var_dump($session);
// Possible to get custom data from session?
$customer = $session->customer;
$customerEmail = $session->customer_email;
// Fulfill the purchase...
$this->db->insertAudioPurchase();
}
http_response_code(200); // PHP 5.4 or greater
});
Is it possible to pass an ID along with the checkout request that Stripe can ping back to allow me to lookup the order and generate a download link?
Upvotes: 34
Views: 31281
Reputation: 317
Metadata can be placed in different areas. It depends on the use case and where you want to access it.
If you want the metadata to be attached to the payment intent (related to the whole checkout), use payment_intent_data.metadata
. If you want to attach the metadata to a specific line item or product, use product_data.metadata
.
See the example below which contains both use cases:
const session = await stripe.checkout.sessions.create({
ui_mode: 'embedded',
line_items: [
{
price_data: {
currency: 'gbp',
product_data: {
name: 'Name',
description: 'Description',
// PRODUCT metadata
metadata: {
product_meta_key: 'product_meta_value'
}
},
unit_amount: 2000,
},
quantity: 1,
},
],
mode: 'payment',
return_url: `...`,
payment_intent_data: {
// PAYMENT metadata
metadata: {
payment_intent_key: 'payment_intent_value',
}
}
});
Upvotes: 1
Reputation: 1
return {
price_data: {
currency: "inr",
product_data: {
name: item.name,
metadata : { //passing extra data here
id : item.id
}
},
unit_amount: item.price*100,
},
quantity: item.quantity,
};
})
You can pass the ID like this.
Upvotes: -1
Reputation: 71
I don't know if you've found the solution but that's the mine. I have used payment intent data and insert into this metadata, that's one of my first help on stackoverflow. I'm searching from two 2 days the solution, and that's it. So i want to help you.
Stripe Docs are not so clearly and useful
payment_intent_data: {
metadata: {
key1 : val1,
ke2 : val2,
key3 : val3,
}
},
Upvotes: 6
Reputation: 109
checkout_session = stripe.checkout.Session.create(
customer_email='[email protected]',
success_url=domain_url + 'success?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain_url + 'cancel/',
payment_method_types=['card'],
mode='subscription',
locale='pl',
line_items=[
{
'price': 'price_*****************',
'quantity': 1,
}
],
subscription_data={'metadata':{'someKeyHere': 'your session variable data'}}
)
Upvotes: 5
Reputation: 5857
Edit: metadata
now does exist on the Session object. Although you will probably need to be on a more recent API version to be able to set it.
metadata
doesn't exist on the Session object yet, so you can't use that.
You can use the client_reference_id
field to store some custom data in your Session. Just be aware that the contents has to be unique. Have a look here.
Upvotes: 26
Reputation: 4024
You can pass an array with key metadata
. Stripe will return this field as you've sent when payment is complete.
You just have to pass as this format.
"metadata": {}
Although, I used it for creating user and saving cards. However, I didn't use it at the time of checkout, but it seems you can pretty much pass this with every API.
From Stripe Doc,
Updateable Stripe objects—including Account, Charge, Customer, PaymentIntent, Refund, Subscription, and Transfer—have a metadata parameter. You can use this parameter to attach key-value data to these Stripe objects.
Metadata is useful for storing additional, structured information on an object. As an example, you could store your user's full name and corresponding unique identifier from your system on a Stripe Customer object. Metadata is not used by Stripe—for example, not used to authorize or decline a charge—and won't be seen by your users unless you choose to show it to them.
Upvotes: 5