I'm trying to create a simple checkout page with wepay and my checkout code (taken from the SDK sample) works great for the owner (me) when I'm signed in, but when logged in as a different user who hasn't created the account (under theirs?) it says the account is invalid or does not belong to the user.
So how are new logged in users supposed to pay to the account (mine), in other words make payments?
Here is the code for reference. The account_id doesn't work for new logged in users because they haven't created it.
$wepay = new WePay($_SESSION['wepay_access_token']);
$checkout = $wepay->request('checkout/create', array(
'account_id' => 501999810,
'amount' => 1.00,
'currency'=> 'USD',
'short_description'=> 'Selling 42 Pens',
'type'=> 'goods'
));
Maybe I have something completely off, but that account_id is where I want to receive payments?
Any help would be appreciated!
Once you register the user, you have to create an actual merchant account by calling /account/create.
Once you have the user's access token, you can call /account/create with the user's access token and the relevant info to actually attach an account to the user. The /account/create call will return an account_id. That account_id is the one you use in the /checkout/create call.
So until you create an account via /account/create the user cannot accept payments.
$productData['data']['seller_data']['wepay_access_token']="STAGE_ea6cd2dffa3dfa23bd4817f210936fadada9fa91e906f353e15813c6cf920fb8";
$productData['data']['seller_data'}['wepay_account_id']="287443494";
$wepay = new WePay($productData['data']['seller_data']['wepay_access_token']);
$checkOutData = array(
//"account_id" => 12345678,
"account_id" => $productData['data']['seller_data'}['wepay_account_id'],
"amount" => 500,
"type" => "goods",
"currency" => "USD",
"short_description" => "Purchase made at test site",
"long_description" => "The charges made in this payment are of the order placed in test",
"delivery_type" => "point_of_sale",
"fee" => array(
"app_fee" => 15,
//'fee_payer' => 'payer_from_app'
'fee_payer' => 'payee_from_app'
),
//"auto_release"=>false,
"payment_method" => array(
"type" => "credit_card",
"credit_card" => array(
"id" => 2178689241,
"auto_capture" => false
)
)
);
try {
$checkoutResult = $wepay->request('checkout/create', $checkOutData);
} catch (Exception $e) {
$data['status'] = '0';
$data['message'] = 'We could not complete checkout!';
return $this->SetOutput();
}
You can get seller access token and account id using
$user_id=20;
$access_token="STAGE_ea6cd2dffa3dfa23bd4817f210936fadada9fa91e906f353e15813c6cf920fb8":
$userName="test user";
$description="sell products";
try {
$wepay = new WePay($access_token);
if (empty($userName)) {
try {
$uresponse = $wepay->request('/user');
$userName = $uresponse->user_name;
} catch (WePayException $e) {
$uresponse['status'] = '0';
$uresponse['message'] = $e->getMessage();
return $uresponse;
}
}
$response = $wepay->request('account/create/', array(
'name' => $userName,
'description' => $description,
'reference_id' => '"' . $user_id . '"'
));
} catch (WePayException $e) {
$response['status'] = '0';
$response['message'] = $e->getMessage();
return $response;
}
Related
How to retrieve the identifier of an existing customer via his email address or create the customer if he does not hesitate when creating a payment with API Stripe?
I searched in the Stripe documentation but couldn't find the answer.
require "Stripe/vendor/autoload.php";
// This is your test secret API key.
\Stripe\Stripe::setApiKey("sk_test_XXX");
header("Content-Type: application/json");
try {
// retrieve JSON from POST body
$jsonStr = file_get_contents("php://input");
$jsonObj = json_decode($jsonStr);
// get customer if exist
$query = \Stripe\Customer::search([
"query" => 'email:\'.'.$user['email'].'.\'',
]);
if ($query->id) {
$customer_ID = $query->id;
} else {
$customer = \Stripe\Customer::create([
"email" => $user["email"],
"description" => 'VIP plan',
]);
$customer_ID = $customer->id;
}
// Create a PaymentIntent with amount and currency
$paymentIntent = \Stripe\PaymentIntent::create([
"customer" => $customer_ID,
"amount" => 1400,
"currency" => "usd",
"automatic_payment_methods" => [
"enabled" => true,
],
]);
$output = [
"clientSecret" => $paymentIntent->client_secret,
];
echo json_encode($output);
} catch (Error $e) {
http_response_code(500);
echo json_encode(["error" => $e->getMessage()]);
}
Your search query is not a simple object but a multidimentional object.
'data' is missing on your object request :
$query->data[0]->id
You can't have access to datas so you might use a for loop as :
if(sizeof($query->data) !== 0)
{
for($i=0;$i<sizeof($query->data);$i++)
{
$customer_ID = $query->data[$i]->id;
}
}
else
{
// Create customer
}
If you're sure to have only one customer, you need to add a limit to the Stripe search query and so, you'll don't need to have for loop :
$query = \Stripe\Customer::search([
"query" => 'email:\'.'.$user['email'].'.\'',
"limit" => 1,
]);
if(sizeof($query->data) !== 0)
{
$customer_ID = $query->data[0]->id;
}
else
{
// create customer
}
Query fields for customers source: https://stripe.com/docs/search#query-fields-for-customers
FIELD USAGE TYPE (TOKEN, STRING, NUMERIC)
------- ---------------------- -----------------------------
created created>1620310503 numeric
email email~"amyt" string
metadata metadata["key"]:"value" token
name name~"amy" string
phone phone:"+19999999999" string
Here is the properly formatted query.
"query" => 'email~"'.$user['email'].'"', "limit" => 1
I'm trying to first create a stripe account, then create the subscription and customer via the created account ID, and then ultimately link the two to create a 'connected' subscriber account on stripe and for it to appear under my connected accounts in my dashboard. So far the script is failing.
// Include Stripe PHP library
require_once 'stripe-php/init.php';
// Set API key
\Stripe\Stripe::setApiKey($STRIPE_API_KEY);
// Create Account
try {
$stripe = \Stripe\Account::create(array(
"email" => $email,
"country" => "US",
"type" => "custom",
'capabilities' => [
'card_payments' => ['requested' => true],
'transfers' => ['requested' => true],
],
));
// Add customer to stripe
try {
$customer = \Stripe\Customer::create(array(
"email" => $email,
"source" => $token
), array("stripe_account" => $stripe->id));
}catch(Exception $e) {
$api_error = $e->getMessage();
}
if(empty($api_error) && $customer){
// Convert price to cents
$priceCents = round($planPrice*100);
// Create a plan
try {
$plan = \Stripe\Plan::create(array(
"product" => [
"name" => $planName
],
"amount" => $priceCents,
"currency" => $currency,
"interval" => $planInterval,
"interval_count" => 1
), array("stripe_account" => $stripe->id));
}catch(Exception $e) {
$api_error = $e->getMessage();
}
if(empty($api_error) && $plan){
// Creates a new subscription
try {
$subscription = \Stripe\Subscription::create(array(
"customer" => $customer->id,
"items" => ["plan" => $plan->id]), array("stripe_account" => $stripe->id));
}catch(Exception $e) {
$api_error = $e->getMessage();
}
echo $api_error;
I have two functions namely charge and subscription, when a successful charge
happens I insert some metadata there look below:
Same for the subscription function:
Then I have a separate file which I will not post here because it only calls to the Charge list API to get all the successful charges to check all the metadatas in there, however I noticed that once I created a subscription via API it's only available there the metadata1 and metadata2.
When I view on the charge created by the subscription nothing was attached to its metadata. How can I attach the metadatas from the subscription to the charge that corresponds to it?
<?php
require_once('stripe-php-master/init.php');
require 'apiKeys.php';
$data = $_REQUEST['data'];
if(isset($data['stripeToken'])){
create_customer($data);
}else{
printResponse($data,"No Token");
}
//Create Customer
function create_customer($data){
try{
\Stripe\Stripe::setApiKey(SK_TEST_KEY);
$customer = \Stripe\Customer::create(array(
"description" => 'Widget Create Customer',
"source" => $data['stripeToken'],
"email" => $data['stripeEmail']
));
$data['customerID'] = $customer->id;
//create_charge($data);
create_subscription($data);
}catch(Exception $e){
echo $e->getMessage();
exit;
}
}//create_customer
//Create charge
function create_charge($data){
try{
\Stripe\Stripe::setApiKey(SK_TEST_KEY);
$settings = [
'currency' => 'aud',
'amount'=>5500,
'description' => 'Widget Payment for ' .$data['widget_name'],
'customer' => $data['customerID'],
'metadata'=>["metadata1" => $data['metadata1'],"metadata2" => $data['metadata2']]
];
// Get the payment token ID submitted by the form:
$charge = \Stripe\Charge::create($settings);
printResponse($data, $charge->status);
}catch(Exception $e){
printResponse($data,$e->getMessage());
exit;
}
}//create_charge
//Create subscription
function create_subscription($data){
try{
\Stripe\Stripe::setApiKey(SK_TEST_KEY);
$settings = [
'customer' => $data['customerID'],
'metadata'=>["metadata1" => $data['metadata1'],"metadata2" => $data['metadata2']],
'items' => [
[
'plan' => $data['widget_class']
]
]
];
$subscription = \Stripe\Subscription::create($settings);
printResponse($data,$subscription->status);
}catch(Exception $e){
printResponse($data,$e->getMessage());
exit;
}
}
function printResponse($data,$status){
//CREATE Response JSON
print_r(json_encode([
'customer_name'=> $data['customer_name'],
'metadata1' => $data['metadata1'],
'metadata2'=> $data['metadata2'],
'payment_status'=>$status
]));
}
?>
I just want the when someone subscribes the charge from the subscription event has the metadata1 and metadata2 attached to it.
I'm sorry for my english.
I'm try to create a charge with a connected account in stripe using standalone account. I'm connecting my accounts using this article in stripe: Sample OAuth Applications. I have 3 accounts: A) Main account. In this account are the clients of our app. Account B and account C are other accounts connected to account A (I see this two accounts connect in the settings of account A. That tells me that two account is already connected, right?). All user's app is in account A and we want share to account B and C, that's our target.
When the accounts has been connected we save in our DB the acces_token and refresh token. The docs of shared customers says that we need create a token with the customer_id and the account_id in order to create a token with the credit card info of customer but when we execute the code it returns an error:
The provided key 'sk_test_********************uJ3l' does not have access to account 'acct_--------------' (or that account does not exist). Application access may have been revoked.
We have test a several combinations of variables pass to api and the result always returns an error.
What are doing wrong in this case. Can you help us???
This is the code that we using: All the comments has been the another test that we try:
public function createtransaction($customer_id, $paymentDesc, $destinationAccount) {
$errors = array();
try {
$secret_key = $this->get_secret_key();
\Stripe\Stripe::setApiKey($secret_key);
// THIS ONLY FOR TESTING PURPOSE. WE WANT SEE IF CAN ACCESS TO CONNECTED ACCOUNT
// Fetching an account just needs the ID as a parameter
// WHIT ACCESS_TOKEN WORKS THE RETRIEVE METHOD
// $account = \Stripe\Account::retrieve('access_token_from_db');
// WHIT ACCOUNT_ID DOES NOT. RETURNS AN ERROR
// $account = \Stripe\Account::retrieve('acct_***********');
// echo "<pre>------";
// print_r($account);
// echo "-----</pre>";
// HERE ONLY WE CAN TEST IF WE CAN CREATE A CUSTOMER. THIS IS ONLY TO CHECK IF THE ACCOUNT IS CONNECTED. THE CUSTOMER ALREADY EXISTS IN MAIN ACCOUNT
// Recommended: sending API key with every request
// \Stripe\Customer::create(
// array("description" => "example#stripe.com"),
// array("api_key" => 'sk_test_***************') // account's access token from the Connect flow
// SAME. WITH stripe_account DOES NOT WORK. WHIT api_key PARAM WORKS WELL
// );
// THE DOCS SAYS WE NEED CREATE A TOEKN WITH customer AND stripe_account, BUT IT RETURNS AN ERROR OF PERMISSION
// Create a Token from the existing customer on the platform's account
// $token = \Stripe\Token::create(
// array("customer" => $customer_id),
// array("stripe_account" => 'acct_********************') // id of the connected account
// );
// echo "<pre>------";
// print_r($token);
// echo "-----</pre>";
// ONE COMBINATION. DOES NOT WORK
// var_dump($customer_id, $paymentDesc, $destinationAccount);
// $charge = \Stripe\Charge::create(array(
// "amount" => $paymentDesc['total'] * 100,
// "currency" => "usd",
// "source" => $token,
// "description" => $paymentDesc['description'],
// 'destination' => $destinationAccount
// ));
//
//
// IT WORKS IN THE MAIN ACCOUNT BUT IT IS NOT OUR GOAL, BUT WE CAN TRANSFER THE MONEY TO ANOTHER CONNECTED ACCOUNT
// $charge = \Stripe\Charge::create(array(
// 'amount' => $paymentDesc['total'] * 100,
// 'currency' => 'usd',
// 'customer' => $customer_id,
// "description" => $paymentDesc['description']
// ));
// ANOTHER COMBINATION. DOES NOT WORK
/*$charge = \Stripe\Charge::create(array(
'amount' => $paymentDesc['total'] * 100,
'currency' => 'usd',
"description" => $paymentDesc['description'],
'customer' => $customer_id
), array('stripe_account' => 'acct_************'));*/
// ANOTHER COMBINATION. DOES NOT WORK
/*$charge = \Stripe\Charge::create(array(
'amount' => $paymentDesc['total'] * 100,
'currency' => 'usd',
"description" => $paymentDesc['description'],
'customer' => $customer_id
), array('api_key' => 'ACCESS_TOKEN_IN_DB'));
echo "<pre>------";
print_r($charge);
echo "-----</pre>";
return array('charge' => $charge);*/
} catch(Stripe_CardError $e) {
$errors = array('error' => false, 'message' => 'Card was declined.', 'e' => $e);
} catch (Stripe_InvalidRequestError $e) {
$errors = array('error' => false, 'message' => 'Invalid parameters were supplied to Stripe\'s API', 'e' => $e);
} catch (Stripe_AuthenticationError $e) {
$errors = array('error' => false, 'message' => 'Authentication with Stripe\'s API failed!', 'e' => $e);
} catch (Stripe_ApiConnectionError $e) {
$errors = array('error' => false, 'message' => 'Network communication with Stripe failed', 'e' => $e);
} catch (Stripe_Error $e) {
$errors = array('error' => false, 'message' => 'Stripe error. Something wrong just happened!', 'e' => $e);
} catch (Exception $e) {
$errors = array('error' => false, 'message' => 'An error has ocurred getting info customer.', 'e' => $e);
}
return $errors;
}
You don't need to save the access_token and refresh_token, only the stripe_user_id containing the connected account id is required to work with Connect.
You can use your platform's secret API key for all the requests and just pass the connected account id to the Stripe-account header as shown in the shared customers documentation. More generally this header can be added to almost every API request to have it directed at a connected account:
https://stripe.com/docs/connect/authentication#authentication-via-the-stripe-account-header
In your case you'd do:
// Create a Token from the existing customer on the platform's account
$sharedToken = \Stripe\Token::create(
array("customer" => CUSTOMER_ID, "card" => CARD_ID),
array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID) // id of the connected account
);
$sharedCustomer = \Stripe\Customer::create(array(
"description" => "Customer for noah.robinson#example.com",
"source" => $sharedToken),
array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
);
You can then create a charge from this shared customer in the same way:
\Stripe\Charge::create(array(
"amount" => 2000,
"currency" => "usd",
"customer" => $sharedCustomer),
array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
);
I have an ecommerce website that redirects to a Paypal express checkout using Omnipay. It will correctly redirect the user to Paypal and return with a successful message with payerID and everything. However, it does not actually take any payment and it does not show up on our paypal account as any payment taken. I am not sure if this is a paypal issue or a configuration problem with Omnipay. I would imagine that Paypal handles this part of it but since it's not working (on our old site it works fine but we do not use Omnipay.)
$gateway = Omnipay::gateway('paypal');
//production
$gateway->setUsername('11111111');
$gateway->setPassword('1111111111');
$gateway->setSignature('111111111');
$cardInput = array(
'firstName' => $info['first_name_bill'],
'lastName' => $info['last_name_bill'],
'billingAddress1' => $info['street_address_1_bill'],
'billingAddress2' => $info['street_address_2_bill'],
'billingPhone' => $info['phone_bill'],
'billingCity' => $info['city_bill'],
'billingState' => $info['state_bill'],
'billingPostCode' => $info['zip_bill'],
'shippingAddress1' => $info['street_address_1_ship'],
'shippingAddress2' => $info['street_address_2_ship'],
'shippingPhone' => $info['phone_ship'],
'shippingCity' => $info['city_ship'],
'shippingState' => $info['state_ship'],
'shippingPostCode' => $info['zip_ship'],
);
$card = Omnipay::creditCard($cardInput);
//live
$response = Omnipay::purchase(
array(
'cancelUrl' => 'http://store.site.com/cart/cancel-payment',
'returnUrl' => 'http://store.site.com/cart/successful-payment',
'amount' => Input::get('total'),
'currency' => 'USD',
'card' => $card,
'description' => 'Stuff'
)
)->send();
if ($response->isSuccessful()) {
return Redirect('cart/successful-payment');
} elseif ($response->isRedirect()) {
$response->redirect(); // this will automatically forward the customer
} else {
return Redirect::back()->with('error', 'There was a problem. Please try again.');
}
} else {
return Redirect::to('cart/successful-payment');
}
So basically what this will do is redirect them to Paypal to make a payment then redirect back to our store. That all works fine. They can input their card number and then come back to our store after submitting it. The issue is after it gets return nothing happens through paypal. No orders or payment are exchanged.
In your return function, the function that gets called when this URL is executed: http://store.site.com/cart/successful-payment you need to call completePurchase. Something like this:
$gateway = Omnipay::gateway('paypal');
//production
$gateway->setUsername('11111111');
$gateway->setPassword('1111111111');
$gateway->setSignature('111111111');
$purchaseId = $_GET['PayerID'];
$response = $gateway->completePurchase([
'transactionReference' => $purchaseId
])->send();
// .. check $response here.