stripe google pay and webhook

google pay 主要前端  后台配合

 

复制代码
<div class="col-sm-6 col-sm-offset-3" id="payment-request-button"></div>
<div id="not-supported-error" style="display: none;">Unfortunately, this payment method is not supported by your device and/or browser...</div>

<script type="text/javascript">
    console.log('One Click Order ver.', '{{ payment_oneclickorder_version }}');
    if (!window.Stripe) {
        $.getScript("https://js.stripe.com/v3/");
    }
</script>


<script type="text/javascript">
    var stripe = null;

    function finishPayment(clientSecret, successUrl, failureUrl) {
        stripe.handleCardPayment(clientSecret).then(function(result) {
            console.log(result);
            
            if (result.error) {
                var status = 'errored';
            } else {
                var status = 'succeeded';
            }
            $.ajax({
                url: 'index.php?route=extension/payment/oneclickorder/send',
                type: 'post',
                data: {status:status,msg:result},
                dataType: 'json',
                complete: function() {
                },
                success: function(json) {
                    if (json['success']) {
                        location = successUrl;
                    }else{
                        location = failureUrl;
                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.log('>>>> one click order error');
                    console.log(xhr.responseText);
                    console.log('<<<< one click order error');
                }
            });
        });
    }

    function initButton() {
        var elements = stripe.elements();
        var paymentRequest = stripe.paymentRequest({
            country: 'US',
            requestPayerName: true,
            requestPayerEmail: true,
            // requestPayerPhone: true,
            currency: '{{ payment_oneclickorder_currency }}'.toLowerCase(),
            total: {
                label: 'Total',
                amount: parseInt('{{ payment_oneclickorder_amount }}'),
            }
        });
        paymentRequest.canMakePayment().then(function (result) {
            console.log('canMakePayment', result);
            if (result) {
                var prButton = elements.create('paymentRequestButton', {
                    paymentRequest: paymentRequest,
                });
                prButton.mount('#payment-request-button');
            } else {    // apple pay is not available
                document.getElementById('payment-request-button').style.display = 'none';
                document.getElementById('not-supported-error').style.display = 'block';
            }
        });
    //支付完成才能触发 paymenthod
        paymentRequest.on('paymentmethod', function (ev) {
            $.ajax({
                url: 'index.php?route=extension/payment/oneclickorder/intentCheckout',
                type: 'post',
                dataType: 'json',
                data: {
                    'amount': '{{ payment_oneclickorder_amount }}',
                    'currency': '{{ payment_oneclickorder_currency }}',
                    'product_id': '{{ product_id }}',
                },
                complete: function() {
                },
                success: function(json) {
                    var clientSecret = json['intent']['client_secret'];
                    stripe.confirmPaymentIntent(clientSecret, {
                        payment_method: ev.paymentMethod.id,
                    }).then(function (confirmResult) {
                        console.log(confirmResult);
                        if (confirmResult.error) {
                            ev.complete('fail');
                        } else {
                            ev.complete('success');
                            console.log(clientSecret);
                            finishPayment(clientSecret, json['success_url'], json['failure_url']);
                        }
                    });
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.log(xhr.responseText);
                    alert('Payment error 405');
                }
            });
        });
    }

    function initStripe() {
        if (window.Stripe) {
            stripe = Stripe('{{ payment_oneclickorder_public_key }}');
            initButton();
        } else {
            setTimeout(function() { initStripe() }, 50);
        }
    }

    initStripe();
</script>
复制代码

后台

复制代码
public function intentCheckout() {
     
    $this->load->language('extension/payment/oneclickorder');
    $this->response->addHeader('Content-Type: application/json');

    $this->load->model('checkout/order');
    $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
    $json = array();

    require_once('./system/library/stripe-php-7.82.0/init.php');
    if($this->config->get('payment_oneclickorder_transaction_mode')) {
      \Stripe\Stripe::setApiKey($this->config->get('payment_oneclickorder_live_private'));
    } else {
      \Stripe\Stripe::setApiKey($this->config->get('payment_oneclickorder_test_private'));
    }

    $amount        = (int)($this->currency->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value'], false) * 100);
    $currency      = $order_info['currency_code'];

    $intent = \Stripe\PaymentIntent::create([
        "amount"                => $amount,
        "currency"              => $currency,
        "setup_future_usage"    => "off_session",
        "payment_method_types"  => ["card"],
        "capture_method"        => 'automatic',
        "description"           => 'OpenCart order #' . $order_info['order_id'],
        "metadata" => [
            "source"      => 'oneclickorder_checkout',
            "version"     => $this->language->get('version'),
            "order_id"    =>  $order_info['order_id'],
            "firstname"   =>  $order_info['firstname'],
            "lastname"    =>  $order_info['lastname'],
            "email"       =>  $order_info['email'],
        ]
    ]);
   
    $json['intent'] = $intent;
    $json['success_url'] = $this->url->link('checkout/success', '', 'SSL');
    $json['failure_url'] = $this->url->link('checkout/failure', '', 'SSL');

    $this->response->setOutput(json_encode($json));
  }
public function webhook() {
    require_once('./system/library/stripe-php-7.82.0/init.php');
    $this->response->addHeader('Content-Type: application/json');
    $payload = @file_get_contents('php://input');
    $this->logmsg('webhook back msg1 '.$payload);
    $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
    $this->logmsg('webhook back time'.$sig_header);
    $event = null;
    try {
      $event = \Stripe\Webhook::constructEvent($payload, $sig_header, $this->config->get('payment_oneclickorder_signing_secret'));
     // $event = \Stripe\Webhook::constructEvent($payload, $sig_header, 'whsec_QkYVcixAn3cDHaOoXsg81sxngPPg1mIK');
      $this->logmsg('webhook event msg'.$event);
    } catch(\UnexpectedValueException $e) {
        $this->logmsg('test 1');
      // Invalid payload
      http_response_code(202); // PHP 5.4 or greater
      return;
    } catch(\Stripe\Error\SignatureVerification $e) {
        $this->logmsg('test 2');
      // Invalid signature
      http_response_code(202); // PHP 5.4 or greater
      return;
    }
    if ($event->type != "payment_intent.succeeded") {
        $this->logmsg('test 3');
      http_response_code(202);
      $json = array('skip' => 'Event type not correct');
      $this->response->setOutput(json_encode($json));
      return;
    }
    
     $this->logmsg('test 4');
     
    if(isset($event->data->object->metadata->order_id)){
          $orderId = $event->data->object->metadata->order_id;
      }elseif(isset($event->data->object->metadata->OrderId)){
          $orderId = $event->data->object->metadata->OrderId;
      }
      $message = 'Payment Intent ID: '.$event->data->object->id. PHP_EOL .'Status: '. $event->data->object->type;
      $this->model_checkout_order->addOrderHistory($orderId, $this->config->get('payment_stripe_order_success_status_id'), $message, false);
    
    http_response_code(200);
  }


    /**
     * 修改订单状态
     */
    public function send() {
        $json = array();
        // Save order in OC
        //1.18 start
        $this->logmsg('post '.$this->session->data['order_id'].json_encode($this->request->post));
        $this->load->model('checkout/order');
        if($this->request->post['status'] == 'succeeded' || $this->request->post['msg']['paymentIntent']['status'] == 'succeeded'){
            $message = 'Payment Intent ID: '.$this->request->post['msg']['paymentIntent']['id']. PHP_EOL .'Status: '. $this->request->post['msg']['paymentIntent']['status'];
            $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('payment_stripe_order_success_status_id'), $message, false);
            $json['success'] = $this->url->link('checkout/success', '', 'SSL');
        } else {
            $message = 'error:'.$this->request->post['msg']['error'];
            $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('payment_stripe_order_failed_status_id'), $message, false);
       }
       //end
        // todo order status id
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
   }
   
 
  
  /**
   * 创建日志
   */
    public function logmsg($data = null) {
        if (!$data) {
            return;
        }
        $log = new Log('stripelog-googlepay-' . date('Ymd') . '.log');
        if (is_array($data)) {
            $log->write(json_encode($data).'\r\n');
        } else {
            $log->write($data);
        }
    }
复制代码

第 1 步:安装 Stripe CLI

wget https://github.com/stripe/stripe-cli/releases/download/v1.7.9/stripe_1.7.9_linux_x86_64.tar.gz

yum
install stripe/stripe-cli/stripe

 数据返回:

复制代码
$.ajax({
                url: 'index.php?route=extension/payment/oneclickorder/send',
                type: 'post',
                data: {status:status,msg:result},
                dataType: 'json',
                complete: function() {
                },
                success: function(json) {
                    if (json['success']) {
                        location = successUrl;
                    }else{
                        location = failureUrl;
                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.log('>>>> one click order error');
                    console.log(xhr.responseText);
                    console.log('<<<< one click order error');
                }
            });
result:{"status":"succeeded","msg":{"paymentIntent":{"id":"pi_3KKGUALlDdeSga8u1SxgdtNO","object":"payment_intent","amount":"7445","automatic_payment_methods":"","canceled_at":"","cancellation_reason":"","capture_method":"automatic","client_secret":"pi_3KKGUALlDdeSga8u1SxgdtNO_secret_NlnCeiEzIxmm02lx4sJbc0urf","confirmation_method":"automatic","created":"1642746034","currency":"usd","description":"OpenCart order #16319","last_payment_error":"","livemode":"true","next_action":"","payment_method":"pm_1KKGU9LlDdeSga8u91641mEK","payment_method_types":["card"],"processing":"","receipt_email":"","setup_future_usage":"off_session","shipping":"","source":"","status":"succeeded"}}}
复制代码
复制代码
$payload = @file_get_contents('php://input');
返回数据: {
"id": "evt_3KKDyvLlDdeSga8u0ourH91J", "object": "event", "api_version": "2020-08-27", "created": 1642736411, "data": { "object": { "id": "pi_3KKDyvLlDdeSga8u0NHENJtA", "object": "payment_intent", "amount": 2000, "amount_capturable": 0, "amount_received": 2000, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ { "id": "ch_3KKDyvLlDdeSga8u0SovpLUG", "object": "charge", "amount": 2000, "amount_captured": 2000, "amount_refunded": 0, "application": null, "application_fee": null, "application_fee_amount": null, "balance_transaction": "txn_3KKDyvLlDdeSga8u0xGY2Bl2", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "calculated_statement_descriptor": "ELECBEE PTE. LTD.", "captured": true, "created": 1642736410, "currency": "usd", "customer": null, "description": "(created by Stripe CLI)", "destination": null, "dispute": null, "disputed": false, "failure_code": null, "failure_message": null, "fraud_details": { }, "invoice": null, "livemode": false, "metadata": { }, "on_behalf_of": null, "order": null, "outcome": { "network_status": "approved_by_network", "reason": null, "risk_level": "normal", "risk_score": 47, "seller_message": "Payment complete.", "type": "authorized" }, "paid": true, "payment_intent": "pi_3KKDyvLlDdeSga8u0NHENJtA", "payment_method": "pm_1KKDyvLlDdeSga8u3Dc8MPFl", "payment_method_details": { "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": null }, "country": "US", "exp_month": 1, "exp_year": 2023, "fingerprint": "T6xnSOemGs7Dt9sM", "funding": "credit", "installments": null, "last4": "4242", "network": "visa", "three_d_secure": null, "wallet": null }, "type": "card" }, "receipt_email": null, "receipt_number": null, "receipt_url": "https://pay.stripe.com/receipts/acct_1IbJcpLlDdeSga8u/ch_3KKDyvLlDdeSga8u0SovpLUG/rcpt_L0ERKJeWPSOCsCYrCYzt0aBxuuUGuh5", "refunded": false, "refunds": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges/ch_3KKDyvLlDdeSga8u0SovpLUG/refunds" }, "review": null, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "510 Townsend St", "line2": null, "postal_code": "94103", "state": "CA" }, "carrier": null, "name": "Jenny Rosen", "phone": null, "tracking_number": null }, "source": null, "source_transfer": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null } ], "has_more": false, "total_count": 1, "url": "/v1/charges?payment_intent=pi_3KKDyvLlDdeSga8u0NHENJtA" }, "client_secret": "pi_3KKDyvLlDdeSga8u0NHENJtA_secret_3AP6QiC3wKAGVwUcCGfIDrCrp", "confirmation_method": "automatic", "created": 1642736409, "currency": "usd", "customer": null, "description": "(created by Stripe CLI)", "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1KKDyvLlDdeSga8u3Dc8MPFl", "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "510 Townsend St", "line2": null, "postal_code": "94103", "state": "CA" }, "carrier": null, "name": "Jenny Rosen", "phone": null, "tracking_number": null }, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null } }, "livemode": false, "pending_webhooks": 2, "request": { "id": "req_fGASHL5gaZKKyn", "idempotency_key": "dae06fc0-11a2-4884-a8f1-5f0fb5222bcd" }, "type": "payment_intent.succeeded" }
复制代码
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];

t=1642736411,v1=e0f0f26770c43f8448a5d8ebc187a5cf6dd5fb07f554d4eb15c6d29f3116ccb5,v0=0133c67013048e67f219da15cfebbbe1afd576cea4392e49288e989354d8033b

 

posted @   楼前竹  阅读(296)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示