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:
- create customer, if not exist
- check if have current card source and, if not, add source
- 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
Post a Comment