条纹付款:由于客户cus_*****没有ID为tok_*****的关联卡而出错


Stripe Payment: Getting Error as Customer cus_***** does not have a linked card with ID tok_*****

在测试模式下,当我创建新客户并尝试付款时,我收到此错误。

客户cus_7Zz2BCnybIZLGw没有带 ID 的链接卡 tok_17Kp8GAwLkQPB7OqrrM73VVI

我使用的卡号:4242424242424242exp_month :122016 exp_year

返回响应为,

Array
(
    [charge_status] => 
    [error_info] => Array
        (
            [type] => invalid_request_error
            [message] => Customer cus_7Zz2BCnybIZLGw does not have a linked card with ID tok_17Kp8GAwLkQPB7OqrrM73VVI.
            [param] => card
            [code] => missing
        )
    [message] => Customer cus_7Zz2BCnybIZLGw does not have a linked card with ID tok_17Kp8GAwLkQPB7OqrrM73VVI.
)

输入电荷数据为,

 $customer = Stripe_Customer::create(array(
      'account_balance' => 100,
      'source' => $token,
      'email' => strip_tags(trim($email))
    )
  );
$customer_id = $customer->id;
$charge   = array(
                'card'          => 4242424242424242, 
                'amount'        => 100, 
                'currency'      => 'cad', 
                'receipt_email' => test@test.com,
                'description'   => 'my payment',
                'customer'      => $customer_id
              );

三种不同的方式可以创建费用:

  • 仅使用 source 参数。在这种情况下,source需要是一个令牌或源 ID(由 Checkout 或 Stripe 创建.js(,即以 tok_src_ 开头的字符串。

  • 仅使用 customer 参数。在这种情况下,customer需要是一个客户 ID,即以 cus_ 开头的字符串。将向客户的默认付款来源收费。

  • 同时具有customersource参数。在这种情况下,customer需要像前面的情况一样是客户 ID,但source应该是已附加到客户的付款来源的 ID。付款来源可以是卡(ID 以 card_ 开头(、银行账户(ID 以 ba_ 开头(或来源(ID 以 src_ 开头(。

在您的情况下,您将在 source 参数中传递令牌 ID,并在 customer 参数中传递客户 ID。

如果这是一张新卡,则应首先使用该令牌在客户上创建卡,然后使用卡 ID 创建费用。如果已为此客户保存了卡,则无需再次收集卡信息(因此根本不需要创建令牌(。

这段代码帮助了我。它也可能对你有所帮助。

Stripe'Stripe::setApiKey(env('STRIPE_SECRET'));
$customer = 'Stripe'Customer::create([
    'name' => 'Jenny Rosen',
    'email' => 'jenyy@hotmail.co.us',
    'address' => [
        'line1' => '510 Townsend St',
        'postal_code' => '98140',
        'city' => 'San Francisco',
        'state' => 'CA',
        'country' => 'US',
    ],
]);
'Stripe'Customer::createSource(
    $customer->id,
    ['source' => $request->stripeToken]
);
Stripe'Charge::create ([
    "customer" => $customer->id,
    "amount" => 100 * 100,
    "currency" => "usd",
    "description" => "Test payment from stripe.test." , 
]);

这是我的解决方案过程,对我有用,以防止重复付款并完成处理,如有必要,请随时改进

  1. 以条带形式添加

     <input type="hidden" name="idempotency" id="idempotency" value="{{ genRandAlphaNumber(8)}}">
    
  2. genRandAlphaNumber 是创建字符串以避免条纹重复支付的功能

    function genRandAlphaNumber($length) {
         $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
         $randomString = '';
         for ($i = 0; $i < $length; $i++) {
             $randomString .= $characters[rand(0, strlen($characters) - 1)];
         }
         return $randomString;
    }
    
  1. 在条纹后处理

     $user = auth()->user();
    
     try {
         $cart = new Cart();
         $cart->user_id = $user->id;
         $cart->save();
         $description = 'description';
         Stripe'Stripe::setApiKey(env('STRIPE_SECRET'));
         $idempotency = preg_replace('/[^a-z'd]/im', '', $request->idempotency);
         $stripe_token = $request->stripeToken;
         //if user's stripe_token is null, create the user      
         if (!$user->stripe_token) {
             $result = 'Stripe'Customer::create(array(
                 'name'   => $user->name .' '. $user->name,
                 "email"  => $user->email,
                 "source" => $stripe_token
             ));
             if($result && $result->id) {
                 $user->stripe_id = $result->id;
                 $user->stripe_token = $stripe_token;
                 $user->save();
             }
         }
    
         //if user has token
         if($user->stripe_token) {
             // charge customer with your amount
             $result = 'Stripe'Charge::create(array(
                 "currency"  => 'usd',
                 "customer"  => $user->stripe_id,
                 "amount"    => $cart->price  * 100,
                 "description" => $description
                 ),
                 ["idempotency_key" => $idempotency,]
             );
             Session::flash('success', 'Payment successful!');
             $cart->status = 4;
             $cart->save();
    
             return redirect()->route('cart.finish', $cart->id);
         }
    
     } catch ('Exception $ex) {
         if ($ex->getStripeCode() == "idempotency_key_in_use") {
             sleep(2);
             //search last cart
             $cart = Cart::whereUser_id($user->id)->whereStatus(4)->orderBy('id', 'DESC')->first();
             if (!is_null($cart)) {
                 Session::flash('success', 'Payment successful!, double payment prevented');
                 return redirect()->route('cart.finish', $cart->id);
             }
             return back();
         }
         if ($ex->getJsonBody()['error']['type'] == "idempotency_error") {
             $cart = Cart::whereUser_id($user->id)->whereStatus(4)->orderBy('id', 'DESC')->first();
             if (!is_null($cart)) {
                 Session::flash('success', 'Payment successful!...');
                 return redirect()->route('cart.membership.update', $cart->id);
             }
             return back();
         }
         return $ex->getMessage();
     }