如何在 stripe checkout.session.completed 上更新我的数据库

Tom*_*čák 6 php

//non working code from stripe documentation

require_once "config.php";

// Set your secret key. Remember to switch to your live secret key in production!
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('EXAMPLE_KEY');


// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'EXAMPLE_SECRET';

$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
    $event = \Stripe\Webhook::constructEvent(
        $payload, $sig_header, $endpoint_secret
    );
} catch(\UnexpectedValueException $e) {
    // Invalid payload
    http_response_code(400);
    exit();
} catch(\Stripe\Exception\SignatureVerificationException $e) {
    // Invalid signature
    http_response_code(400);
    exit();
}

function fulfill_order($session) {
    // TODO: fill me in
    $order_id = $session->client_reference_id;

}

function create_order($session) {
    // TODO fill me in
}

function email_customer_about_failed_payment($session) {
    // TODO fill me in
}

switch ($event->type) {
    case 'checkout.session.completed':
        $session = $event->data->object;

        $data = $database->update("orders", [
            "payment_status" => 1
        ], [
            "id" => 64
        ]);

        if($data){
            echo 'success';
        }

        // Save an order in your database, marked as 'awaiting payment'
        create_order($session);

        // Check if the order is paid (e.g., from a card payment)
        //
        // A delayed notification payment will have an `unpaid` status, as
        // you're still waiting for funds to be transferred from the customer's
        // account.
        if ($session->payment_status == 'paid') {
            // Fulfill the purchase
            fulfill_order($session);
        }

        break;

    case 'checkout.session.async_payment_succeeded':
        $session = $event->data->object;

        // Fulfill the purchase
        fulfill_order($session);

        break;

    case 'checkout.session.async_payment_failed':
        $session = $event->data->object;

        // Send an email to the customer asking them to retry their order
        email_customer_about_failed_payment($session);

        break;
}

http_response_code(200);

?>
Run Code Online (Sandbox Code Playgroud)
//non working code from stripe documentation

require_once "config.php";

// Set your secret key. Remember to switch to your live secret key in production!
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('EXAMPLE_KEY');


// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'EXAMPLE_SECRET';

$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
    $event = \Stripe\Webhook::constructEvent(
        $payload, $sig_header, $endpoint_secret
    );
} catch(\UnexpectedValueException $e) {
    // Invalid payload
    http_response_code(400);
    exit();
} catch(\Stripe\Exception\SignatureVerificationException $e) {
    // Invalid signature
    http_response_code(400);
    exit();
}

function fulfill_order($session) {
    // TODO: fill me in
    $order_id = $session->client_reference_id;

}

function create_order($session) {
    // TODO fill me in
}

function email_customer_about_failed_payment($session) {
    // TODO fill me in
}

switch ($event->type) {
    case 'checkout.session.completed':
        $session = $event->data->object;

        $data = $database->update("orders", [
            "payment_status" => 1
        ], [
            "id" => 64
        ]);

        if($data){
            echo 'success';
        }

        // Save an order in your database, marked as 'awaiting payment'
        create_order($session);

        // Check if the order is paid (e.g., from a card payment)
        //
        // A delayed notification payment will have an `unpaid` status, as
        // you're still waiting for funds to be transferred from the customer's
        // account.
        if ($session->payment_status == 'paid') {
            // Fulfill the purchase
            fulfill_order($session);
        }

        break;

    case 'checkout.session.async_payment_succeeded':
        $session = $event->data->object;

        // Fulfill the purchase
        fulfill_order($session);

        break;

    case 'checkout.session.async_payment_failed':
        $session = $event->data->object;

        // Send an email to the customer asking them to retry their order
        email_customer_about_failed_payment($session);

        break;
}

http_response_code(200);

?>
Run Code Online (Sandbox Code Playgroud)

我目前正在用 stripe 编写我的第一个电子商店。我有一个表格,用户填写运输信息和结帐按钮。在结帐按钮上单击表单,将其提交到数据库并分配唯一的订单 ID 和默认 payment_status = false。然后用户被重定向到条带预构建结账页面。

付款成功后,我想从 stripe 接收 webhook,如果付款成功,请在我的数据库中为已完成付款的某些用户 (order_id) 更新 payment_status = true。

我有多个问题:

  1. 我如何知道订单的 ID?...有什么方法可以将其与电子邮件一起传递到 checkout.session,然后在我的 webhook 端点中通过事件接收它?

  2. 我已经尝试过示例代码(由 stripe 提供)来更新 checkout.session.completed 上的数据库...但是此代码不起作用:(...所以我在互联网上找到了另一个适合我的代码...但我不认为在 2020 年仍然可以使用此代码,因为它不会验证 webhook 是否由 stripe:// 发送

关于如何使其发挥作用有什么建议吗?

ves*_*lov 1

我偶然发现了同样的问题。我通过在 Orders 表中创建 checkoutSession 列来完成此操作。我通过 createCheckoutSession 方法传递我的订单 ID,在创建结账会话并将其作为对 Stripe 的响应发送回之后,我设置了订单的 checkoutSession id。成功结帐后,stripe 会将响应发送回您的 webhook,您可以在那里获取结帐会话,并将其与订单中的 checkoutSession 进行比较并更新它。这是我在 Symfony 框架中的代码:

带有付款按钮的模板:

fetch('{{ path('create_checkout_session', { orderId: order.id }) }}', {
   method: 'POST',
}) // This function creates the checkout session on my backend and passes the order id as parameter
Run Code Online (Sandbox Code Playgroud)

创建结帐会话并将其发送到 stripe:

try {
    $session = \Stripe\Checkout\Session::create([
                    'payment_method_types' => ['card'],
                    'line_items' => $lineItems,
                    'mode' => 'payment',
                    'success_url' => $domain . $this->generateUrl('checkout_success'),
                    'cancel_url' => $domain . $this->generateUrl('cart_list'),
                ]);

                $em = $this->getDoctrine()->getManager();
                $order = $em->getRepository('App:Order\Order')->findOneBy(['id' => $orderId]);
                $order->setCheckoutSession($session->id);
                $em->persist($order);
                $em->flush();
                // I save the checkout session id in my order entity here
            }
Run Code Online (Sandbox Code Playgroud)

接收条带响应的 Webhook:

switch ($event->type) {                                                                                    
    case 'checkout.session.completed':                                                                     
        $session = $event->data->object;    
                                                                                                                          
    if ($session->payment_status == 'paid') {                                                          
        $em = $this->getDoctrine()->getManager();                                                      
        $order = $em->getRepository('App:Order\Order')->findOneBy(['checkoutSession' => $session->id]);
        $order->setPaymentStatus($session->payment_status);                                            
        $em->persist($order);                                                                          
        $em->flush();                                                                                  
    }                                                                                                  
                                                                                                       
    break;                                                                                             
Run Code Online (Sandbox Code Playgroud)