I'm working with the open source ticket system called Attendize.
They already have the payment provider Stripe integrated. Now I'm trying to make this work with the payment provider Mollie.
The problem is I keep stumbling on this error:
My code looks like this:
$transaction_data += [
'transactionId' => $event_id . date('YmdHis'),
'returnUrl' => route('showEventCheckoutPaymentReturn', [
'event_id' => $event_id,
'is_payment_successful' => 1
]),
];
$apiKey = "test_gSDS4xNA96AfNmmdwB3fAA47******";
$gateway->setApiKey($apiKey);
$transaction = $gateway->purchase($transaction_data);
$response = $transaction->send();
if ($response->isSuccessful()) {
session()->push('ticket_order_' . $event_id . '.transaction_id',
$response->getTransactionReference());
return $this->completeOrder($event_id);
} elseif ($response->isRedirect()) {
/*
* As we're going off-site for payment we need to store some data in a session so it's available
* when we return
*/
session()->push('ticket_order_' . $event_id . '.transaction_data', $transaction_data);
Log::info("Redirect url: " . $response->getRedirectUrl());
$return = [
'status' => 'success',
'redirectUrl' => $response->getRedirectUrl(),
'message' => 'Redirecting to ' . $ticket_order['payment_gateway']->provider_name
];
// GET method requests should not have redirectData on the JSON return string
if($response->getRedirectMethod() == 'POST') {
$return['redirectData'] = $response->getRedirectData();
}
return response()->json($return);
} else {
// display error to customer
return response()->json([
'status' => 'error',
'message' => $response->getMessage(),
]);
}
When I debug my code he's going into the elseif ($response->isRedirect()) {. I am being redirected to Mollie and a can do a successful payment. But when I am being redirect back to http://myurl.dev/e/1/checkout/success?is_payment_successful=1 I'm getting the error.
UPDATE:
In my return function I have the following code:
public function showEventCheckoutPaymentReturn(Request $request, $event_id)
{
if ($request->get('is_payment_cancelled') == '1') {
session()->flash('message', 'You cancelled your payment. You may try again.');
return response()->redirectToRoute('showEventCheckout', [
'event_id' => $event_id,
'is_payment_cancelled' => 1,
]);
}
$ticket_order = session()->get('ticket_order_' . $event_id);
$gateway = Omnipay::create($ticket_order['payment_gateway']->name);
$gateway->initialize($ticket_order['account_payment_gateway']->config + [
'testMode' => config('attendize.enable_test_payments'),
]);
$transaction = $gateway->completePurchase($ticket_order['transaction_data'][0]);
$response = $transaction->send();
if ($response->isSuccessful()) {
session()->push('ticket_order_' . $event_id . '.transaction_id', $response->getTransactionReference());
return $this->completeOrder($event_id, false);
} else {
session()->flash('message', $response->getMessage());
return response()->redirectToRoute('showEventCheckout', [
'event_id' => $event_id,
'is_payment_failed' => 1,
]);
}
}
The problem (error) is with $response = $transaction->send();.
The array $ticket_order['transaction_data'][0] contains this:
Array
(
[amount] => 80
[currency] => EUR
[description] => Order for customer: niels#email.be
[transactionId] => 120170529082422
[returnUrl] => http://eventy.dev/e/1/checkout/success?is_payment_successful=1
)
UPDATE 2:
I've added $gateway->setApiKey($apiKey); in my return function. But the problem is that my response is NOT successful. So he doesn't go into $response->isSuccessful(). When I dump my $response variable just before he checks if it's successful it shows this: https://pastebin.com/NKCsxJ7B.
You can see there's an error like this:
[error] => Array
(
[type] => request
[message] => The payment id is invalid
)
The payment in Mollie looks like this:
UPDATE 3:
In my return function I tried to check the status of the response object like this : $response->status(). This gave me the following error:
Call to undefined method Omnipay\Mollie\Message\CompletePurchaseResponse::status()
Then I tried $response->getStatus() but this gave me nothing back.
What #Daan said in his comment is correct, you are getting the error from the landing page, not the page that creates the transaction.
On that landing page you will have a call like this:
$omnipay->completePurchase($data);
In that #data array you need to include the 'transactionReference' field which should be one of the POST parameters that your http://myurl.dev/e/1/checkout/success?is_payment_successful=1 URL received.
Probably a useful debugging aid is to have the code at that URL print out or log the entire $_POST array and you can use that to check what parameter you need to pull from that array. It varies a bit between gateways.
This might have something to do with this ticket: https://github.com/thephpleague/omnipay-eway/issues/13
To solve this check I would suggest checking status code with
if ($request->status() == 201) {
//successful created
}
My theory is that it is checking against 200
The function is defined here:
https://github.com/thephpleague/omnipay-mollie/blob/master/src/Message/AbstractResponse.php
public function isSuccessful()
{
return !$this->isRedirect() && !isset($this->data['error']);
}
It will probably fail because you expect a redirect!
201 because of my Postman test below
Related
I have the following function, but when I run it in Postman to see the result, it doesn't print any value to me, it doesn't even give me an error. The var_dump set if it detects them, but the array does not... I think there is something wrong in the method updateOrCreate , because when I print this variable with var_dump, I can't see anything in the console.
This is the function:
public function createBidRival(Request $request)
{
$response = array('code' => 400, 'error_msg' => []);
if (!$request->id_karatekas) array_push($response['error_msg'], 'id_karateka is required');
if (!$request->id_participant_bid_send ) array_push($response['error_msg'], 'id_participant_bid_send is required');
if (!$request->id_participant_bid_receive) array_push($response['error_msg'], ' id_participant_bid_receive is required');
if (!$request->bid_rival) array_push($response['error_msg'], 'bid rival is required');
if (!count($response['error_msg']) > 0) {
try {
var_dump($request->id_karatekas);
var_dump($request->id_participant_bid_send);
var_dump($request->id_participant_bid_receive);
var_dump($request->bid_rival);
$bidRival = new BidBetweenRivals();
$bidRival = BidBetweenRivals::updateOrCreate(
[
'id_participant_bid_send' => $request->id_participant_bid_send,
'id_participant_bid_receive' => $request->id_participant_bid_receive,
'id_karatekas' => $request->id_karatekas
],
[
'id_participant_bid_send' => $request->id_participant_bid_send,
'id_participant_bid_receive' => $request->id_participant_bid_receive,
'id_karatekas' => $request->id_karatekas,
'bid_rival' => $request->bid_rival
]
);
$bidBetweenRivals->save;
$response = array('code' => 200, 'bidBetweenRivals' => $bidRival, 'msg' => 'Bid created');
}catch(\Exception $exception) {
$response = array('code' => 500, 'error_msg' => $exception->getMessage());
}
}
}
Dump to see whether if (!count($response['error_msg']) > 0) true or not and also dump something in the catch block to see if exception is occurring or not.
You can also test by commenting out the updateOrCreate part to see if it is interfering.
I am trying to make a bitcoin API to receive payments on my site and I am using laravel and php 7.2. This is part of my coingate api code
$post_params = array(
'order_id' => $transaction->id,
'token' => $transaction->hash,
'price' => $transaction->price,
'currency' => $currency,
'receive_currency' => $receive_currency,
'callback_url' => route('ipn.coingate',['token' => $transaction->hash]),
'cancel_url' => route('billing.fail'),
'success_url' => route('billing.success'),
);
and this is call back url script (ipn controller)
$order = Transaction::find($request->input('order_id'));
if ($request->input('token') == $order->hash) {
$savedata = null;
if ($request->input('status') == 'paid') {
if ($request->input('price') >= $order->price) {
$savedata['confirmation'] = $request->input('id');
$savedata['gateway_response'] = json_encode($request->all());
$savedata['status'] = 'paid';
//Update product sales
$this->salesupdate($da->product_id);
//Save order
$this->neworder($order->user_id,$da->product_id,$order->price,$order->hash,$order->id);
//Save user transaction
$this->newusertransaction($da->user_id,$da->price);
//Credit seller
$this->creditseller($da->product_id);
}
The issue here is that when payment on coingate is done, it returns to the success_url without doing the functions in the callback url(ipn Controller)
I want when the payment is done to return to callback url(ipn Controller)
to do what in the file
success_url is where the customer gets redirected when they finish the payment. Callback_url is where CoinGate will send the callbacks too, the callback function has to be triggered by a callback from Coingate and not from finishing a payment.
I am trying to implement what mentioned here but getting error:
Array ([type] => invalid_request_error [message] => No such customer: 92 [param] => customer)
I am using Laravel Cashier:
$user = User::find($current_user_id);
if ($user->charge(100, [
'customer' => 92,
'source' => $token,
'description' => "Testing Payment Deduction for Brief"
])
) {
print "Awesome";
} else {
print "it failed";
}
Using this code to create customer fails as it trie to create a record in users table which does not need as I already have a user created:
$customer = $user->create(array(
'email' => 'customer#example.com',
'card' => $token
));
How can I send my existing customer ID and email to Stripe?
This issues erupts only due to one reason and that is token generated by following function.
Stripe.card.createToken($form, stripeResponseHandler)
in stripeResponseHandler(status, response)
response.id is the token value. so please use this token to create subscription or whatever... Thanks
I am using Omnipay to allow users to pay using Cardsave.
I have the following:
\Omnipay::setTestMode(true);
$transactionId = date('YmdHis').$booking->space->id.$booking->user->id;
$response = $gateway->purchase([
'amount' => $booking->price,
'currency' => 'GBP',
'card' => $card,
'transactionId' => $transactionId,
'cancelUrl' => \base_url('cardsave/cancel/'.$booking->id),
'returnUrl' => \base_url('cardsave/confirm/'.$booking->id)
])->send();
if ($response->isSuccessful()) {
$transactionReference = $response->getTransactionReference();
//save the transaction reference in case of refund
return ['status' => 'success', 'message' => 'Reservation process complete'];
} elseif ($response->isRedirect()) {
\Log::info('3DSecure redirect');
$booking->addAdditional(['3dsecure_transaction_id' => $transactionId]);
return [
'status' => 'redirect',
'form_html' => $response->getRedirectResponse()->getContent()
];
}
throw new PaymentException ($response->getMessage());
and my confirm url goes to the following method:
$transactionId = $booking->getAdditional('3dsecure_transaction_id');
$response = $gateway->completePurchase([
'amount' => $amount,
'transactionId' => $transactionId,
'currency' => 'GBP',
])->send();
if ($response->isSuccessful()) {
$transactionReference = $response->getTransactionReference();
return $this->finalise($booking, $transactionReference);
} else {
$this->cancel($booking);
}
But looking through the code for league/omnipay-cardsave, I see the following:
$md = $this->httpRequest->request->get('MD');
$paRes = $this->httpRequest->request->get('PaRes');
if (empty($md) || empty($paRes)) {
throw new InvalidResponseException;
}
So my question is (and I realise it is probably dumb, but I can't seem to grok this, for some reason), where is that request coming from, if I just instantiated the gateway?
I think I am doing this wrong.
EDIT:
I have discovered that the return call from the 3DSecure thing comes with the MD and PaRes values as POST parameters. This allows me to set them on the gateway. How do I do that? Is it done automatically when I instantiate the gateway?
I was right, the question was dumb.
After reading the code, and trying it out, I found out that the AbstractGateway uses Symfony's request class to automatically pickup POST variables, amongst which are in this case, 'MD' and 'PaRes'.
In fact, it says so in the CompletePurchase class:
$md = $this->httpRequest->request->get('MD');
$paRes = $this->httpRequest->request->get('PaRes');
httpRequest is setup in AbstractGateway.
Basically, it just works.
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.