php - Stripe invalid request - using a token more than once -


code:

stripe::setapikey($stripe_secret_key); stripe::setapiversion('2017-02-14');    // either create new customer object or retrieve existing customer object  $db->query(" select stripecustomertoken stripe_ids upper(useremail) = upper(:email) "); $db->bind(':email', $user_email); $db->execute(); $customer_token = $db->fetchsinglecolumn();  if(!$customer_token) {     $customer = stripe_customer::create(         [             'card' => $stripe_card_token,             'description' => $user_email,             'email'=>$user_email         ],         $stripe_access_token     );      $customer_token = $customer->id;      $db->query(" insert stripe_ids (useremail, stripecustomertoken) values (:e, :custid) ");     $db->bind(':e', $user_email);     $db->bind(':custid', $customer_token);     $db->execute(); }  if(!$customer_token)     throw new exception('no stripe customer token detected. payment not processed.');  $customer = stripe_customer::retrieve($customer_token);    // using token id, retrieve full token object , retrieve fingerprint `card.fingerprint` attribute  $current_card = stripe_token::retrieve($stripe_card_token); $current_card_fingerprint = $current_card->card->fingerprint; $current_card_id = $current_card->card->id;    // iterate through list of customer's saved sources , check if has same value `fingerprint`  $source_exists = false; foreach($customer->sources->data $i => $fingerprint) {     if($current_card_fingerprint === $fingerprint)         $source_exists = true; }    // if not, add card customer object  if(!$source_exists)     $customer->sources->create(['source' => $stripe_card_token]);  $customer->default_source = $current_card_id; $customer->save();    // create charge using customer id , card id  $charge = [     'customer' => $customer->id,     'source' => $current_card_id,     'amount' => $total_gross_received_cents,     'currency' => 'eur',     'description' => $transaction_description_str,     'application_fee' => $databiz_fee ];  $charge_obj = stripe_charge::create($charge, $stripe_access_token);  if(empty($charge_obj))     throw new exception('no stripe charge object detected. payment not processed.');  $charge_token = $charge_obj->id; 

issue:

each time customer uses application, must enter cc details. therefore want to:

  1. create customer, if not exist
  2. check if have current card source and, if not, add source
  3. charge used card

i running trouble whereby returning customer's default card not being updated used card (resulting in funds coming default), added card id charge object, , saved current card customer's default.

the issue that, on live transaction, getting invalidrequest exception - cannot use token more once.

can point out me going wrong?

the token you're providing when adding card customer (with $customer->sources->create(...)) has been consumed api request. should check integration ensure $stripe_card_token contains "fresh" token created checkout or elements.

a few other things noticed:

  • you're using connect direct charges. means customer objects must exist on connected account, not on platform's account. when retrieve customer, don't specify connected account's api key, request issued on platform's account , fail (since customer id doesn't exist on platform's account)

  • you're using old version (1.x) of stripe's php library. should consider upgrading more recent version. require updating code new syntax (stripe_class -> \stripe\class)

  • when looking if card exists on customer, iterate on $customer->sources->data. note when retrieving customer object, attribute contain @ 10 sources. if customer has more 10 sources, need use pagination retrieve full list.

    note if use recent version of stripe's php library, can use auto-pagination feature handle easily.


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -