BugHunterUK
BugHunterUK

Reputation: 8968

Is it possible to pass custom data to stripe checkout?

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

Answers (6)

Samueljh1
Samueljh1

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

Rahul Patil
Rahul Patil

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

Marco Cirillo
Marco Cirillo

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

paeduardo
paeduardo

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'}}
        )

stripe dashboad now shows metadataenter code here

Upvotes: 5

Paul Asjes
Paul Asjes

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

A J
A J

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

Related Questions