Testing Stripe - Creating charge for Checkout session - php

I'm using Stripe checkout and I have it all working as follows:
Create Session, redirect to Checkout, handle order fulfillment on redirect with passed through session_id.
I'm trying to write a test for this but I can't figure out how to fake a Stripe Checkout charge onto the Stripe Session & PaymentIntent.
I'm using the PHP Library and I've tried this:
$paymentIntent = PaymentIntent::retrieve($session->payment_intent);
dd($paymentIntent->charges->create([
'source' => 'tok_visa_debit',
'currency' => 'gbp',
'amount' => 100,
]));
But I am getting an error: Stripe\Error\InvalidRequest : Received unknown parameter: payment_intent
What is the correct way to test this works?

Related

stripe manual confirmation + connected account failing (confirmation_method + stripe_account)

I'm using Stripe's PHP SDK in a Laravel project, and I'm having a weird issue with 3d secure payments.
PHP Version : 7.4
Stripe-PHP : 7.75.0
When creating a PaymentIntent on behlaf of a connected stripe account using the stripe_account parameter, and the confirmation_method: 'manual' parameter, there's alway an error stating:
This PaymentIntent pi_XXXXXX cannot be confirmed using your publishable key because its confirmation_method is set to manual. Please use your secret key instead, or create a PaymentIntent with confirmation_method set to automatic.
This is how I created my intent:
$paymentIntentParameters = array(
'amount' => $priceAsCents,
'currency' => 'eur',
'payment_method' => $paymentMethodId,
'confirmation_method' => 'manual',
'confirm' => true,
);
$paymentIntent = StripePaymentIntent::create(
$paymentIntentParameters,
['stripe_account' => $store->stripe_token]
);
I followed everything said here: https://github.com/stripe-samples/accept-a-card-payment/tree/master/without-webhooks
I'm in a case where the webhook doesn't work for me, and where the confirmation_method: 'automatic' doesn't do the job too, because the confirmation is done on the frontend, and we only want cofirmations on the backend.
Is there any quick fix for this?
In order to perform server-side (manual) confirmation, you want to follow this doc. Specifically, instead of using handleCardPayment on the frontend, you use createPaymentMethod on the frontend, use the resulting PaymentMethod with a PaymentIntent on the backend, and then confirm on the backend. The linked doc shows the exact steps.
And for the 3d secure, you need to add handleCardPayment.

Laravel Cashier charge method fails with 3d secure on single charge

I need help with Laravel Cashier.
I'm using laravel cashier on backend and vue on client side.
On client I setup stripe object, elements and card.
In the meanwhile I request to serve a client_secret making a PaymentIntent
$payment_intent = PaymentIntent::create(
['amount' => $request["price"],
'currency' => "eur",
'payment_method_types' => ['card'],
'customer' => $stripe_customer->id,
], [
'api_key' => config('services.stripe.secret'),
]);
When user input credit card data and confirm using the client_secret
I call this function in client side
this.stripe.confirmCardPayment(this.stripe_payment_intent.client_secret, {
payment_method: {
card: this.stripe_card,
billing_details: {
name: 'Test Name'
}
},
setup_future_usage: 'off_session'
})
...
On then I call the server passing the result.
On the server side
$stripeCharge = $request->user()->charge(
$request["paymentIntent"]["amount"], $request["paymentIntent"]["payment_method"]
);
It works fine, withouth sca (3d secure)
But when the test card require 3d secure (4000002500003155 or 4000002760003184) on the client all goes fine, displaying the 3d secure
dialog, the confirmCardPayment succeed, but in last step when calling charge I got
The payment attempt failed because additional action is required before it can be completed.
Why? All the actions is performed on the client side.. why the server not agree?
p.s. I need only single charge without store any payment method
The problem was that confirmCardPayment already charge the user.
So calling again in the server side make the error because double charge on 3d secure card is not possible.
I had to remove charge on the server side and using PaymentIntent::retrieve in order to verify the status and check if already processed in my business logic.

Stripe payment issue with "application fee"

I am facing following problem while doing stripe payment.
Uncaught exception 'Stripe\Error\Authentication' with message 'Only Stripe Connect platforms can work with other accounts. If you specified a client_id parameter, make sure it's correct
I am using the php code below:
$charge = \Stripe\Charge::create(
array(
"amount" => $amount*100, // amount in cents
"currency" => $currency, // usd
"source" => $token,
"description" => $description,
"application_fee" => 123 // amount in cents
),
array("stripe_account" => 'cus_7Gt1CAXXXXXX') // CONNECTED_STRIPE_ACCOUNT_ID
);
And another question is that from where I can get CONNECTED_STRIPE_ACCOUNT_ID like that acct_12QkqYGSOD4XXXXXX. if possible please send code or screenshot or location to get these account id.
Can anyone please help to solve that problem?
You have to create 'Connect with Stripe' button in your app which will redirect user to fill form to authorize your app.
After Clicking on Authorize button(by user,after filling form properly), it will redirect to 'Redirect URI(redirect URI is that URI which you fill in Platform Setting)'.
After redirection stripe will add scope and authorization code to your URI
for eg. your URI: www.yoursite.com
you will get www.yoursite.com?scope=read_write&authorization_code=AUTHORIZATION_CODE
After That follow----> https://stackoverflow.com/a/34714859/5467417

Omnipay: How to retrieve original transaction ID when using WorldPay callback

When processing a callback from a WorldPay transaction, what is the best way to retrieve the original transactionId that was passed to Omnipay?
This would be needed to update the appropriate database record with the result of the transaction, for instance.
I can see that there is a getTransactionReference() method available on the response, but not a getTransactionId() method (which would presumably access the 'cartId' value returned by WorldPay).
I'm guessing that the cartId value could be accessed directly, but is there a gateway-agnostic way to do this?
You should pass the transactionId back to yourself by using a custom returnUrl.
First, when you set up Worldpay:
Log into your WorldPay Merchant Admin Interface
Under Installations, click Setup next to your Installation ID
In the Payment Response URL field, enter <wpdisplay item=MC_callback>
Make sure the Payment Response enabled? option is selected
Then, when you make the initial purchase request with Omnipay, pass a custom returnUrl. For example:
$response = $gateway->purchase(array(
'amount' => '10.00',
'currency' => 'USD',
'returnUrl' => 'https://www.example.com/return?transactionId=123'
))->send();
That way, on your callback/return page, you can load the original transaction details before calling completePurchase():
$transaction = Transaction::find($_GET['transactionId']);
$response = $gateway->completePurchase(array(
'amount' => $transaction->amount,
'currency' => $transaction->currency,
))->send();

Credit Card processing using Pin Payments - pin.net.au - using omnipay gateway, card_token method (pin.js)

I am trying to integrate Pin.net.au CC processing into my site. I am using Omnipay library to make the calls.
To not store CC details in my server, I am using the Pin.js token method.
On form submit page (after user fills in personal and CC details) javascript does a 'prevent default' and sends the data from forms (browser) straight to pin.net.au servers. Server sends a card_token in response and resubmits the form to my server.
This token is recieved successfully and I can output it in my tests.
I get into trouble when I take that token and send a purchase request to pin.net.au. According to the API docs, I need not send user and card details when I send the token (the entire point of the token, really). I send this token along with other compulsory bits like email, amount, description etc.
This works when I cURL on my terminal and I get a charge success.
However, sending this purchase/charge request using the Omnipay library, each time I get a 422 (invalid resource) that asks for the user details and CC information. It should have populated this stuff from the token I sent.
I have scoured the API docs of both Omnipay and Pin.net.au. I don't seem to be doing anything wrong. What am I missing?
Here's my charge request:
$gateway = GatewayFactory::create('Pin');
$gateway->setSecretKey('MY_SECRET_KEY');
$response = $gateway->purchase([
'email' => 'user#email.com',
'description' => 'Package',
'amount' => '99',
'currency' => 'AUD',
'card_token' => Input::get('card_token'),
'ip_address' => Input::get('ip_address')
])->send();
Finally, it shouldn't really matter but if you'd like to know, I'm using Laravel 4.
Your example request has an amount of 99, the minimum amount for a Pin Payments charge is $1 (amount = 100).
I don't think this is the problem you are referring to though, it looks like Omnipay does not support using the card_token gear. If you go look over here - https://github.com/adrianmacneil/omnipay/blob/master/src/Omnipay/Pin/Message/PurchaseRequest.php#L34 - you can see Omnipay isn't sending the card_token field with it's request, it only tries to send card details, which obviously aren't present from your example!
Perhaps you could get in touch with the Omnipay developers or write a pull request yourself!
This is fixed in Omnipay v1.0.4 - you should be able to use the token like this:
$gateway = GatewayFactory::create('Pin');
$gateway->setSecretKey('MY_SECRET_KEY');
$response = $gateway->purchase([
'description' => 'Package',
'amount' => '99.00',
'currency' => 'AUD',
'token' => Input::get('token'),
'ip_address' => Input::get('ip_address'),
'card' => ['email' => 'user#email.com'],
])->send();

Categories