As per the stripe documentation here we read all the information and know the ideas about the SCA. But I am not getting any related API documentation. So, I am confusing how to implement in our existing PHP code and what are the parameters we will add. Please find below my example of code:
\Stripe\Stripe::setApiKey(API_KEY_HERE);
$customer = \Stripe\Token::create(
array("card" => array(
"name" => $arg['name'],
"number" => $arg['number'],
"exp_month" => $arg['exp_month'],
"exp_year" => $arg['exp_year'],
"cvc" => $arg['cvc']
))
);
/* some other code here */
$charge = \Stripe\Charge::create(
array(
"amount" => $arg['amount'],
"currency" => "usd",
"description" => "Subscription Charge",
"customer" => $customer->id
)
);
/* some other db related code here */
I have shared the code. Could you please let us know what we need to change for SCA?
I just answered this question where OP did a great job on the question.
Perhaps her code can help you see how you need to implement this using JS in the
front-end and PHP in the backend.
Stripe - Payment Intents (3d secure issue)
i was having a problem with Wepay API. My codes are correct but it keeps on returning an error saying "payment method does not exist or does not belong to app". I already configured the permission to allow tokenized credit cards. But still. Any feedback is greatly appreciated. Thanks!
Here is my code
require_once('public/payment/wepay/wepay.php');
$user = API::get_client(['fldClientEmail' => $email])->first();
// change to useProduction for live environments
\Wepay::useStaging(WEPAY_CLIENT_ID, WEPAY_CLIENT_SECRET);
$wepay = new \WePay($user->fldClientWepayTokenAccess);
// $wepay = new \WePay(WEPAY_ACCESS_TOKEN);
// dd($email);die;
// dd($user->fldClientWepayAccountID);die;
// charge the credit card
$response = $wepay->request('checkout/create', [
'account_id' => $user->fldClientWepayAccountID,
'amount' => number_format(Input::get('amount_tipped'),2),
'currency' => 'USD',
'short_description' => 'A short description',
'type' => 'goods',
'payment_method' => array(
'type' => 'credit_card',
'credit_card' => array(
'id' => Input::get('cc_id')
)
)
]);
// display the response
return $response;
Make sure that when you follow the tutorial from their docs, you replace all of the credentials from the examples. I was using their Javascript library for the tokenization of the credit card with the client_id they provided.
response = WePay.credit_card.create({
"client_id": YOUR.CLIENT.ID.HERE,
"user_name": valueById('name'),
"email": valueById('email'),
"cc_number": valueById('cc-number'),
"cvv": valueById('cc-cvv'),
"expiration_month": valueById('cc-month'),
"expiration_year": valueById('cc-year'),
"address": {
"postal_code": valueById('postal_code')
}
If you don't provide your own, is like you were creating those credit cards for another application that's not yours.
If this didn't do the trick, check this article, hopefully it does:
https://support.wepay.com/hc/en-us/articles/203609273-WePay-API-Error-Codes
I know that asking this here could be throwing a stone in the dark because I found 2 other similar questions but none had any answers to it.
Any way, I hope someone has already found the solution for this and can shed a light on it.
Let me explain the scenario first as it might help with finding a solution:
I am creating stripe custom connect accounts like this:
$acct = \Stripe\Account::create(array(
"country" => "US",
"type" => "custom",
"email" => "email#mail.com"
));
Then I add Bank Accounts to them like so:
$account->external_accounts->create(
array(
'external_account' => array(
"object" => "bank_account",
"country" => "US",
"currency" => "usd",
"account_holder_name" => 'Jane Austen',
"account_holder_type" => 'individual',
"routing_number" => "111000025",
"account_number" => "000123456789"
)
));
This all works fine so far....
Now, what I need to do is to be able to transfer Money/Payments from the connected custom accounts into their Bank accounts.
For that purpose, I will need to add a Credit Card to that connetced account so that card details can be used for making payments into the Bank Accounts.
So I went ahead and tried this:
$account->external_accounts->create(
array(
'external_account' => array(
"object" => "card",
"exp_month" => 8,
"exp_year" => 2018,
"number" => "4012888888881881",
"currency" => "usd",
"cvc" => "123"
)
));
And that did NOT work and gave me this error:
Requests made on behalf of a connected account must use card tokens from Stripe.js, but card details were directly provided.
So I changed my strategy and tried this:
$result = \Stripe\Token::create(
array(
"card" => array(
"name" => "Some Name",
"exp_month" => 8,
"exp_year" => 2018,
"number" => "4012888888881881",
"currency" => "usd",
"cvc" => "123"
)
));
$token = $result['id'];
$account->external_accounts->create(
array(
'external_account' => array(
"object" => "card",
"source" => "".$token.""
)
));
However, this gave me the same error message!!!
This is very frustrating because if you look at their own API documentation, you will clearly see that they say:
source required
Either a token, like the ones returned by Stripe.js, or a dictionary containing a user's credit card details (with the options shown below). Stripe will automatically validate the card.
This can be seen here:
https://stripe.com/docs/api#create_card
Could someone please advice on this issue?
I cannot use stripe.js in my project so I will need to use the API.
Any help would be greatly appreciated.
Thanks in advance.
First Edit:
Here is a strange one.. I generated a Stripe card token from here:
https://codepen.io/fmartingr/pen/pGfhy
Note that the above codepen uses the stripe.js to generate the tokens....
and tried to use the token from there in my PHP code like so:
$account->external_accounts->create(
array(
'external_account' => array(
"object" => "card",
"source" => "tok_1AqPXeDQzcw33c71uncYBFdm"
)
));
but this gives me the exact same error:
Requests made on behalf of a connected account must use card tokens from Stripe.js, but card details were directly provided.
Please use this it will add your external account
$result = \Stripe\Token::create(
array(
"card" => array(
"name" => "Some Name",
"exp_month" => 8,
"exp_year" => 2018,
"number" => "4012888888881881",
"currency" => "usd",
"cvc" => "123"
)
));
$token = $result['id'];
$account->external_accounts->create(
array(
'external_account' => "".$token.""
));
I create a APP in which i use Braintree Payment Gateway. In my application i make options to set different currency, am just know that how to set currency when i set sale transaction param.
here is my code
$result = Braintree\Transaction::sale([
'amount' => '50.00',
'creditCard' => array(
'cardholderName' => 'Test Name',
'number' => '4000111111111511',
'expirationDate' => '12/2018',
'cvv' => '123',
),
'options' => [ 'submitForSettlement' => true]
]);
All of my transaction made in US Dollar, but i want to make transaction in different currencies.
Please someone give me the solution.
thanks
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
You will need to set up a different merchant account for each currency you would like to process. Then, when processing a transaction for a specific currency, you can pass in the merchant account id to the transaction sale method.
In addition, to keep your PCI compliance burden low, you will want to pass a nonce to your server in place of the credit card details.
$merchantAccountId = someFunctionToLookupCorrectMerchantIdBasedOnCurrency();
$result = Braintree\Transaction::sale([
'amount' => '100.00',
'paymentMethodNonce' => nonceFromTheClient,
'merchantAccountId' => $merchantAccountId,
'options' => [
'submitForSettlement' => True
]
]);
I am working with the magento api and I have run into a bit of an issue with creating an order. I have been able to get everything up to creating the order to work correctly. The issue that I am seeing is when I call the method to create the order I always get the exception: Credit card number mismatch with credit card type.
I am running Magento ver. 1.6.2.0
I have verified that the card I am testing with works via the magento frontend.
Any help with this is greatly appreciated.
This is the test code that I am using:
<?php
$proxy = new SoapClient('http://localhost/index.php/api/soap/?wsdl');
$sessionId = $proxy->login('shopapi', 'test123');
// Create a quote, get quote identifier
$shoppingCartId = $proxy->call( $sessionId, 'cart.create');
// Set customer, for example guest
$customerAsGuest = array(
"firstname" => "testFirstname",
"lastname" => "testLastName",
"email" => "test#test.com",
//"website_id" => "0",
//"store_id" => "0",
"mode" => "guest"
);
$resultCustomerSet = $proxy->call($sessionId, 'cart_customer.set', array( $shoppingCartId, $customerAsGuest) );
// Set customer addresses, for example guest's addresses
$arrAddresses = array(
array(
"mode" => "shipping",
"firstname" => "testFirstname",
"lastname" => "testLastname",
"company" => "testCompany",
"street" => "testStreet",
"city" => "testCity",
"region" => "CA",
"postcode" => "90049",
"country_id" => "US",
"telephone" => "0123456789",
"fax" => "0123456789",
"is_default_shipping" => 0,
"is_default_billing" => 0
),
array(
"mode" => "billing",
"firstname" => "testFirstname",
"lastname" => "testLastname",
"company" => "testCompany",
"street" => "testStreet",
"city" => "testCity",
"region" => "CA",
"postcode" => "90049",
"country_id" => "US",
"telephone" => "0123456789",
"fax" => "0123456789",
"is_default_shipping" => 0,
"is_default_billing" => 0
)
);
$resultCustomerAddresses = $proxy->call($sessionId, "cart_customer.addresses", array($shoppingCartId, $arrAddresses));
// add products into shopping cart
$arrProducts = array(
array(
"product_id" => "1",
"qty" => 1
)
);
$resultCartProductAdd = $proxy->call($sessionId, "cart_product.add", array($shoppingCartId, $arrProducts));
// get list of products
$shoppingCartProducts = $proxy->call($sessionId, "cart_product.list", array($shoppingCartId));
// set payment method
$paymentMethod = array(
"method" => "authorizenet",
"cc_type" => 'MC',
"cc_number" =>'5555555555554444' ,
"cc_exp_month" => 9,
"cc_exp_year" => 2014,
"cc_cid" => 123
);
$resultPaymentMethod = $proxy->call($sessionId, "cart_payment.method", array($shoppingCartId, $paymentMethod));
// create order
$resultOrderCreation = $proxy->call($sessionId,"cart.order",array($shoppingCartId));
var_dump($resultOrderCreation);
?>
Your call to cart_payment.method is succeeding, according to your post, so the CC number is validating to be a MC card, as expected.
The problem is that Magento, due to PCI concerns, does NOT save the CC number in the database (in most cases).
So, as you are sending payment details, along with CC number and CID, in one request and then creating the order in another, the state is lost and the CC number and CID are blanked out.
When the order is created, the payment data is validated a second time and when that happens, it has an empty CC number with a type of MC, causing the fault you see.
Unfortunately, I do not see a way to make cart.order accept payment data as a work around.
You could write a module to extend the checkout APIs with a new method that does both steps in a single call and that would likely solve the problem.
I ran into this issue as well. My solution was to create a custom SOAP endpoint which handled all of the order creation and submission logic at once without multiple API calls.
Even this way, I was getting card type mismatch exceptions.
The trick was once I set the payment info, collect totals, and save quote, with the getPayment->importData method, it seems to forget the card info. Probably for (not the best way to handle) PCI-DSS compliance.
To solve it, I added another getPayment->importData line after saving the quote, before submitting the order.
This is achieved without changing any of the core files.
See example:
public function customCheckout($checkoutData=false)
{
if(!$checkoutData){
Mage::throwException("No checkout data received.");
}
if(!json_decode($checkoutData)){
Mage::throwException("Bad checkout data received.");
}
$data = json_decode($checkoutData);
$email = 'email#email.cc';
// get the basic store info to associate with order
$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();
// begin checkout with a quote
$quote = Mage::getModel('sales/quote')->setStoreId($store->getId());
// set customer by email
$customer = Mage::getModel('customer/customer')
->setWebsiteId($websiteId)
->loadByEmail($email);
// handle customer not exists by creating a new customer
if($customer->getId() == ''){
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstName("Bob")
->setLastName("Loblaw")
->setEmail($email)
->setPassword('password');
$customer->save();
}
// assign customer to SO quote
$quote->assignCustomer($customer);
// do we want to send a confirmation email to the customer?
// my guess is we would handle that in a separate service.
$quote->setSendConfirmation(0);
// add products to quote
foreach($data->products as $item){
$product = Mage::getModel('catalog/product')->load($item->id);
$quote->addProduct($product,new Varien_Object(array('qty'=>$item->qty)));
}
// set SO billing address
$billingAddress = $quote->getBillingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => $data->customer->firstName,
'middlename' => '',
'lastname' => $data->customer->lastName,
'suffix' => '',
'company' => '',
'street' => array(
'0' => 'street1',
'1' => 'street2'
),
'city'=>'city',
'country_id'=>'US',
'region'=>'WA',
'postcode'=>'98101',
'telephone' => '425-425-4254',
'fax' => '789-789-7897',
'vat_id' => '',
'save_in_address_book' => 0
));
// set SO shipping address, this will probably be the location of sale, on-site
$shippingAddress = $quote->getShippingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => $data->customer->firstName,
'middlename' => 'middle',
'lastname' => $data->customer->lastName,
'suffix' => '',
'company' => '',
'street' => array(
'0' => 'street1',
'1' => 'street2'
),
'city'=>'city',
'country_id'=>'US',
'region'=>'WA',
'postcode'=>'98201',
'telephone' => '425-425-4254',
'fax' => '789-789-7897',
'vat_id' => '',
'save_in_address_book' => 0
));
// set shipping method, if it's sold on site we aren't charging for delivery
$shipMethod='freeshipping_freeshipping';
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($shipMethod)
->setPaymentMethod($data->payment->method);
// set payment method
$quote->getPayment()->importData(array(
'method' =>$data->payment->method,
'cc_type' =>$data->payment->type,
'cc_number' =>$data->payment->number,
'cc_exp_year' =>$data->payment->expYear,
'cc_exp_month'=>$data->payment->expMonth,
));
// collect totals, save quote
$quote->collectTotals()->save();
// turn the quote into an order
$service = Mage::getModel('sales/service_quote',$quote);
// set payment method A SECOND TIME!!!!!!!!!!!!!
$quote->getPayment()->importData(array(
'method' =>$data->payment->method,
'cc_type' =>$data->payment->type,
'cc_number' =>$data->payment->number,
'cc_exp_year' =>$data->payment->expYear,
'cc_exp_month'=>$data->payment->expMonth,
));
$service->submitAll();
$increment_id = $service->getOrder()->getRealOrderId();
$quote = $customer = $service = null;
$retval = new stdClass;
$retval->orderId = $increment_id;
return json_encode($retval);
}
I have never done successful API transactions to the payment method code authorizenet. This only always succeeds via frontend, not sure why.. nor have I had time to investigate why. Although what I have always done instead is to use authorizenet_direct post instead. My reasoning behind this / how I stumbled upon this is that the same also applies to the Paypal payment methods. API seems to only work with paypal_direct or paypaluk_direct. Try it! it should work. At the very least, this works for me.
$paymentMethod = array(
"method" => "authorizenet_directpost",
"cc_type" => 'MC',
"cc_number" =>'5555555555554444' ,
"cc_exp_month" => 9,
"cc_exp_year" => 2014,
"cc_cid" => 123
);
Actually I just discovered a way to take authorize.net payments via the API.
First in /app/code/core/Mage/Payment/Model/Method/Cc.php, uncomment the line about saving the cid, so the function look like this on line 65
public function prepareSave()
{
$info = $this->getInfoInstance();
if ($this->_canSaveCc) {
$info->setCcNumberEnc($info->encrypt($info->getCcNumber()));
}
$info->setCcCidEnc($info->encrypt($info->getCcCid()));
$info->setCcNumber(null)
->setCcCid(null);
return $this;
}
And then in the main model file of your payment method, make sure the variable is set to:
protected $_canSaveCc = true;
I've tested 2 payment methods using this and both work fine via API now.
this is my solution:
goto /app/code/core/Mage/Payment/Model/Method/Cc.php
and see function :
public function prepareSave()
{
$info = $this->getInfoInstance();
if ($this->_canSaveCc) {
$info->setCcNumberEnc($info->encrypt($info->getCcNumber()));
}
//$info->setCcCidEnc($info->encrypt($info->getCcCid()));
$info->setCcNumber(null)
->setCcCid(null);
return $this;
}
only comment line :
$info->setCcNumber(null)
->setCcCid(null);