'How to Specify MOTO (Mail Order Telephone Order) for Stripe/PHP?
I am struggling to figure out how to specify a MOTO payment with Stripe API and PHP. I believe I specify MOTO in the payment_method_options on the confirm (javascript), and I have to specify confirm = true in the create (PHP). I am struggling to get the example from here to work with MOTO although it works fine without.
script.js (I add payment_method_options: { card: {moto:true} }) to confirmCardPayment...
var pay = function(stripe, card, clientSecret) {
changeLoadingState(true);
// Initiate the payment.
// If authentication is required, confirmCardPayment will automatically display a modal
stripe
.confirmCardPayment(clientSecret, { payment_method: { card: card }, payment_method_options: { card: {moto:true} } })
.then(function(result) {
if (result.error) {
// Show error to your customer
showError(result.error.message);
} else {
// The payment has been processed!
orderComplete(clientSecret);
}
});
};
confirm-intent.php I specify confirm=true and include payment_method in the output...
use Stripe\PaymentIntent;
use Stripe\Stripe;
require '../vendor/autoload.php';
header('Content-Type: application/json');
Stripe::setApiKey('sk_test_xxxxxxxxxxxxx');
$paymentIntent = PaymentIntent::create([
'amount' => 2000,
'currency' => 'gbp',
'payment_method_types' => ['card'],
'confirm' => true
]);
$output = [
'publishableKey' => 'pk_test_xxxxxxxxxxxxx',
'clientSecret' => $paymentIntent->client_secret,
'payment_method' => $paymentIntent->id,
];
echo json_encode($output);
The error I am currently getting is...
PHP message: PHP Fatal error: Uncaught (Status 400) (Request req_1D9UTDO2IIp8zI) You cannot confirm this PaymentIntent because it's missing a payment method. You can either update the PaymentIntent with a payment method and then confirm it again, or confirm it again directly with a payment method.
The payment method is the id of the payment intent, I think. I have put it into the output of the payment intent script but this does not work. Any ideas? Thank you.
Solution 1:[1]
If you want to perform a MOTO stripe payment, there are requirements as follows:
- You need to activate the MOTO payment option with stripe directly.
- You need to perform a single payment action, which is a paymentIntent with confirm=true. Making a paymentIntent first with confirmCardPayment later won't work in this case.
The paymentIntent action in this case would look like this: (the following is a curl request, you can convert it to your backend language)
curl https://api.stripe.com/v1/payment_intents \
-u sk_test_NfCI7U9wkvqjrgJRFirEuwjN \
-d amount=1099 \
-d currency=eur \
-d "payment_method_data[type]"=card \
-d "payment_method_data[card][number]"=4242424242424242 \
-d "payment_method_data[card][exp_month]"=4 \
-d "payment_method_data[card][exp_year]"=24 \
-d "payment_method_data[card][cvc]"=242 \
-d "payment_method_options[card][moto]"=true \
-d confirm=true
It will return either an error or a successful payment result, which you can use for your further actions.
Alternatively you can first create the paymentMethod and then make a confirmed intent with paymentMethod ID (to avoid sending card details directly and to make use of stripe card input UI elements). See more about how to create a payment method first here: https://stripe.com/docs/payments/accept-a-payment-synchronously#create-a-paymentmethod
If you do it, your MOTO API call would look like this:
curl https://api.stripe.com/v1/payment_intents \
-u sk_test_NfCI7U9wkvqjrgJRFirEuwjN \
-d amount=1099 \
-d currency=eur \
-d "payment_method"=<YOUR paymentMethodID> \
-d "payment_method_options[card][moto]"=true \
-d confirm=true
Solution 2:[2]
resolved using
var url = "https://api.stripe.com/v1/payment_intents";
var httpRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
httpRequest.Headers["Authorization"] = "Bearer sk_test_YOURKEY...";
var data = "amount=1099¤cy=eur&payment_method_data[type]=card&payment_method_data[card][number]=4242424242424242&payment_method_data[card][exp_month]=4&payment_method_data[card][exp_year]=24&payment_method_data[card][cvc]=242&payment_method_options[card][moto]=true&confirm=true";
using (var streamWriter = new System.IO.StreamWriter(httpRequest.GetRequestStream())){streamWriter.Write(data);}
var httpResponse = (System.Net.HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new System.IO.StreamReader(httpResponse.GetResponseStream())) {var result = streamReader.ReadToEnd();}
Response.Write("Result:" + httpResponse.StatusCode + ";");
Then on first payment you'lll get an error
>curl -u "sk_test_51KiFsQIZBabXT9vC1SZAcFMJpgdBHFHa1rMBjaMntI4gGEAGciPFkrERfISvM37sS1SNHcJThaRwjgwLh0bW8u9n00mjcVcPFN:" --data "amount=1099¤cy=eur&payment_method_data[type]=card&payment_method_data[card][number]=4242424242424242&payment_method_data[card][exp_month]=4&payment_method_data[card][exp_year]=24&payment_method_data[card][cvc]=242&payment_method_options[card][moto]=true&confirm=true" https://api.stripe.com/v1/payment_intents
{
"error": {
"message": "Sending credit card numbers directly to the Stripe API is generally unsafe. We suggest you use test tokens that map to the test card you are using, see https://stripe.com/docs/testing.",
"type": "invalid_request_error"
}
}
you must go to
https://dashboard.stripe.com/settings/integration
click advanced options and set the toogle option to allow data from card directly
and done.
Reemerb that you first need to ask manually8 stripe to give you enable the MOTO option
Solution 3:[3]
finally working with below code:
var url = "https://api.stripe.com/v1/payment_intents";
var httpRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.Headers["Authorization"] = "Bearer sk_test_YOUR KEY";
var data = "amount=1099¤cy=eur&payment_method_data[type]=card&payment_method_data[card][number]=4242424242424242&payment_method_data[card][exp_month]=4&payment_method_data[card][exp_year]=24&payment_method_data[card][cvc]=242&payment_method_options[card][moto]=true&confirm=true";
using (var streamWriter = new System.IO.StreamWriter(httpRequest.GetRequestStream())) { streamWriter.Write(data); }
var httpResponse = (System.Net.HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new System.IO.StreamReader(httpResponse.GetResponseStream())) { var result = streamReader.ReadToEnd(); }
Response.Write("Resultado:" + httpResponse.StatusCode + ";");
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Devmyselz |
| Solution 3 | Devmyselz |
