Not able to get transaction id in subscription plan - php

I am working with Stripe payment option for my project. I have a recurring option and that's why I have created plans in subscription page.
After creating plans I have defined my plan when a new stripe customer register.
try {
$customer = \Stripe\Customer::create([
'source' => $token,
'email' => $email,
'plan' => '20-39-R',
'metadata' => [
"First Name" => $first_name,
"Last Name" => $last_name
]
]);
} catch (\Stripe\Error\Card $e) {
return redirect()->route('order')
->withErrors($e->getMessage())
->withInput();
}
When I have dump($customer) variable I am not getting transaction id.
Any idea why I am not getting transaction id during customer creation?

The customer object doesn't store a list of transaction ids which I think is what you'd call the id of the charge made on that customer's card right? The customer holds information about the sources (used to pay) and subscriptions that are created after a customer is subscribed to a plan.
Here you can see a sub_XXXXX in subscriptions[data][0][id] which corresponds to the id of the subscription that was created on that customer for your plan 20-39-R.
If you want the charge id, ch_XXXXX you would use the List ChargesAPI and pass the customer id, cus_XXXXX, in the `customer parameter to limit the charges to the ones created on that customer. The first one in the list would be the latest charge and likely the one corresponding to your subscription. You could confirm this by checking the invoice associated with the charge and confirming that it's for your subscription.

Related

Stripe shows no such token: tok_xxxxxxx for destination charge

I am trying to create a destination charge from my customer to one of the connected account.
\Stripe\Stripe::setApiKey(STRIPE_SECRET_KEY); //Origin Stripe Secret Key
try {
$connectd_account_id = 'acct_XXXXXXX';
$customer_id = 'cus_XXXXXXX'
// sharing my customer with connected account and creating a token.
$token = \Stripe\Token::create(
["customer" => $customer_id], //doctor stripe customer id
["stripe_account" => $connectd_account_id]); //Lab Stripe Account
// I am receiving response ** No such token: tok_xxxxxxx **
$charge = \Stripe\Charge::create(array(
"amount" => 10000,
"currency" => 'USD',
"source" => $token->id,
"application_fee_amount" => 2000,
"transfer_data" => [
"destination" => $connectd_account_id,
],
)
);
} catch (Exception $e) {
$error = $e->getMessage();
}
everytime I receive
No such token: tok_xxxxxxx
What's my mistake here I can't locate. Please help.
If you're creating a destination charge, the card token and customer and related objects should all be created on your platform account. Your platform account is the one interacting with the cardholder and processing the payment, there is then just a transfer of funds within Stripe to the destination account.
Your code appears to be attempting to clone saved card details from your platform to the destination account, which is not what you would do for a Destination charge(you'd only do this if you were using Direct charges where the payment is processed on the connected account and thus need to copy payment information there).
In short, you should omit the code for creating a token, and instead when creating the charge, pass something like "source" => $customer_id, to charge the customer details on your platform.

Stripe : Add new card to already created customer

I have a stripe customer already added, I am figuring out to add new card to customer. I searched around but couldn't found anything confirmed to asnwer my following questions.
Do stripe have any form of their own to add new card ?
Is following is the correct way to add new card ?
$customer = \Stripe\Customer::retrieve(Auth::user()->stripe_key);
// Got the customer details successfully from the above call.
$card = $customer->cards->create(
array(
"card" =>
array(
"number"=> "4242424242424242",
"exp_month" => "12",
"exp_year" => "2016",
"cvc" => "123"
)
)
);
Stripe does not have a direct form specifically for adding a new card to a customer, however you can use Checkout or Elements to collect the customer's card details.
The process for adding a new card to a customer would be as follows:
Collect and tokenize the customer's card details using Checkout or Elements[0]. This will give you a Stripe token representing the card.
Send this token to your backend, where you can use something similar to the following code to save the card to the customer:
$token = $_POST['stripeToken']; #for example
$customer = \Stripe\Customer::retrieve(Auth::user()->stripe_key);
$customer->sources->create(array("source" => $token));
[0] - https://stripe.com/docs/checkout or https://stripe.com/docs/stripe-js/elements/quickstart
[1] - https://stripe.com/docs/api/php#create_card

Stripe Checkout - Subscription Issue with Recognized Stripe User

I have Stripe working great. Upon a customer's donation, a new Subscription is created, and it works great - except if Stripe recognizes the email and says, "Enter the verification code."
If the customer does that, for some reason, a new subscription is not created and the customer is not charged.
Here is my charge-monthly.php
<?php
require_once('init.php');
// Set your secret key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_**************");
// Get the credit card details submitted by the form
$token = $_POST['stripeToken'];
$email = $_POST['stripeEmail'];
$amount = $_POST['amount'];
$finalamount = $amount * 100;
$dollars = ".00";
$plan = "/month";
$dash = " - ";
$monthlyplan = $amount .$dollars .$plan .$dash .$email;
//Create monthly plan
$plan = \Stripe\Plan::create(array(
"name" => $monthlyplan,
"id" => $monthlyplan,
"interval" => "month",
"currency" => "usd",
"amount" => $finalamount,
));
// Create a Customer
$customer = \Stripe\Customer::create(array(
"source" => $token,
"description" => "MONTHLY DONATION",
"plan" => $monthlyplan,
"email" => $email, )
);
?>
Any ideas why when Stripe recognizes the user and he is "logged in" it does not allow me to create a subscription?
In the Stripe log, I receive this 400 error:
{
"error": {
"type": "invalid_request_error",
"message": "Plan already exists."
}
}
But there definitely isn't a plan created... ah!
The reason your request is failing is because if a user comes back with the same email address and wants to sign up for the same plan, you already have an existing plan with that name,
$monthlyplan = $amount .$dollars .$plan .$dash .$email;
so your call to \Stripe\Plan::create will return an error and cause the rest of your calls to fail here.
You could add something like a unique id or time to your plan id.
http://php.net/manual/en/function.time.php
http://php.net/manual/en/function.uniqid.php
Some other ways that folks typically handle this are:
Create a single plan for $1, and then adjust the quantity when creating your subscription. So a monthly plan for $1 with quantity of 100, would charge $100 month.
Store the amount that a customer will pay within your application. Subscribe your customers to a $0/month plan. Use webhooks to listen for invoice.created events. Have your webhook handler add an Invoice Item every month for the balance.

how to create customer and charge subscription at same time?

I'm using stripe and had all my subscriptions working properly before.
Just recently I am trying to move the same code to a different stripe account and I am receiving errors when trying to charge a subscription.
<?php
require_once('../stripe-php-master/init.php');
// (switch to the live key later)
\Stripe\Stripe::setApiKey("sk_test_hlQNSE1fy1cGmsqDSbR9LfDF");
try
{
$customer = \Stripe\Customer::create(array(
'email' => $_POST['stripeEmail'],
'source' => $_POST['stripeToken'],
'plan' => 'basic_annually'
));
header('Location: ../../subscription-success.html');
exit;
}
catch(Exception $e)
{
header('Location:oops.html');
error_log("unable to sign up customer:" . $_POST['stripeEmail'].
", error:" . $e->getMessage());
}
this is returning the following error
unable to sign up customer: 'test#example.com', error:No such plan: basic_monthly; one exists with a name of basic_monthly, but its ID is 504102373103330.
Plan objects have both an id and a name attribute. id is the plan's unique identifier while name is its display name.
When creating a customer or a subscription, the value of the plan parameter must be set to a valid plan ID, not to a plan's name.
In your case, the error message explicitly tells you that there is plan with "basic_monthly" as its name, but the plan's id is 504102373103330, so that's the value you'd need to pass in the plan parameter to create a subscription to that plan.
you must change secret and test api keys

How to add multiple cards in same customer in stripe payment gateway using php

i was implementing stripe payment in testing mode.Here i got an error like Same token is used again. is there any different way to add multiple cards.
or i need to call retrive function in a separate page so that conflict of same token never come again.And how should i set a card default.
public function createToken($data)
{
$TokenResult=Token::create(array(
"card" => array(
"name" => $data['name'],
"number" => $data['card_number'],
"exp_month" => $data['month'],
"exp_year" => $data['year'],
"cvc" => $data['cvc']
)));
//echo "<pre>";;
//print_r($TokenResult);
$this->token=$TokenResult['id'];//store token id into token variable
$this->chargeCard($this->token); //call chargecard function via passing token id
}
/*
* function to create customer
*/
public function createCustomer($data,$token=null)//pass form data and token id
{
$customer=Customer::create(array(
"email"=>$data['email'],
"description" => $data['name'],
"source" => $token // obtained with Stripe.js
));
$customerId=$customer['id'];
$this->retriveCustomer($customerId,$token);
}
/*
* function to retrive current customers for adding multiple cards to same customers*/
public function retriveCustomer($customerid,$token)
{
echo $this->token;
//die('here');
$retriveResult=Customer::retrieve($customerid);
$retriveResult->sources->create(array("source" =>$this->token));
return $retriveResult;
}
First, please note that unless you are PCI certified and allowed to directly manipulate card data, you should never have access to card numbers in your server-side code.
Card tokens should be created client-side, via Checkout or Elements. Your server should only deal with client-side created card tokens and never with PCI-sensitive information (card numbers and CVCs). This will greatly decrease the burden of PCI compliance and make you eligible for PCI SAQ A.
In PHP, this is how you'd add a card to an existing customer object:
$customer = \Stripe\Customer::retrieve("cus_...");
$card = $customer->sources->create(array(
"source" => $token // token created by Checkout or Elements
));
I think you dont need to create a token in case of adding new card. It helps while you update certain card. So the flow of addition will be same as you created for first card.
I dont know which stripe version you are using, I am using bit old:
$card_array = array(
'card' => array(
'number' => $number,
'exp_month' => $exp_month,
'exp_year' => $exp_year,
'cvc' => $cvc,
'name' => $name
)
);
$card_obj = $this->setData("\Stripe\Customer", "retrieve", $customer_id, TRUE);
$card = $card_obj->sources->create($card_array);
Stripe's docs don't explain a lot of the more nuanced procedures so you have to do a lot of testing.
Assuming you have a customer object $cu, with the token you get from checkout or whatever you use:
$card = $cu->sources->create(['source'=>$token]);
will add a card to the customer. It just adds the card to the list; subsequent calls will add cards to the list. Note that it does not check for duplicates, so the same card can be on the list multiple times. It will also not set the new card to the active card. To make a card the default (or active), use
$cu->default_source = $card
$cu->save();
Using the older card interface:
$cu->card = $token;
$cu->save();
The new card will replace the default card. It will NOT make the previously default card inactive; it will delete the current default and make the new card the active default. The card interface is the easiest if you're just allowing 1 card to be attached to a customer at a time.

Categories