I have issue with coingate api - php

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.

Related

Laravel Omnipay - The transactionReference parameter is required

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

Does the creditCard function exist in Omnipay PayPal Express? Or only in PayPal Pro?

This question is maybe similar to THIS and THIS but I'm not entirely sure.
I've made a shopping cart that sends the product details and quantity/total amount to Paypal on checking out. I'm using Laravel 4 and the Omnipay Paypal plugin (Paypal_Express). I can send product details fine using the 'setItems' function and am now looking to pre-populate the credit card field on the Paypal summary page with my User's details.
I have seen in other SO threads such as THIS that other people use the creditCard function to pass details to the Paypal summary credit card info page.
My question: 1) Do you need to be using Paypal_Pro for the creditCard function to worK?
I get this error when I try (call_user_func_array() expects parameter 1 to be a valid callback, class 'Omnipay\Common\GatewayFactory' does not have a method 'creditCard').
I don't want to enter all the credit card details - Just speed the process up by entering the User's Name, Adress etc...
Also I tried changing to Paypal_Pro and it didn't work. (same error as above) I changed config plus gateways in my payment controller.
2)How do you change PayPal_Express to PayPay_Pro?
My code:
public function postPayment() {
$cart = Session::get('cart');
$allProducts = [];
foreach($cart->aContents as $productID=>$quantity){
$product = Product::find($productID);
// get the product id
// load the product from the id
// store data in the allProduct array
$allProducts[] = array('name' => $product->name, 'quantity' => $quantity, 'price'=> $product->price);
}
$cardInput = array(
'first_name' => Input::get('first_name'),
'last_name' => Input::get('last_name'),
'address1' => Input::get('address1'),
'city' => Input::get('city'),
'zip' => Input::get('zip'),
'email' => Input::get('email')
);
$card = Omnipay::creditCard($cardInput);
$params = array(
'cancelUrl' => \URL::to('cancel_order'),
'returnUrl' => \URL::to('payment_success'),
'amount' => Input::get('price'),
'currency' => Input::get('currency'),
'card' => $card,
);
Session::put('params', $params);
Session::save();
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('tjmusicmanagement-facilitator_api1.gmail.com');
$gateway->setPassword('K2LWQVP2L8472BPY');
$gateway->setSignature('AwTOuAJWzCkdc5PldYeiz.l3iy5UAwOucYW6EFLLA9zUQqXaWyEGbebq');
$gateway->setTestMode(true);
$gateway->setLogoImageUrl(URL::to('images/logoSmall.png'));
$response = $gateway->purchase($params)->setItems($allProducts)->send();
if ($response->isSuccessful()) {
// payment was successful: update database
print_r($response);
} elseif ($response->isRedirect()) {
// redirect to offsite payment gateway
$response->redirect();
} else {
// payment failed: display message to customer
echo $response->getMessage();
}
}
And also the ignited\laravel-omnipay\config.php is unchanged (though I did try changing the driver)
return array(
// The default gateway to use
'default' => 'paypal',
// Add in each gateway here
'gateways' => array(
'paypal' => array(
'driver' => 'PayPal_Express',
'options' => array(
'solutionType' => '',
'landingPage' => '',
'headerImageUrl' => ''
)
)
)
);
Thanks for your tinme!!
EDIT: Here is my getSuccessPayment function where I can hopefully get the users paypal details (just name and address etc) from paypal. But how and where do I specify this?
public function getSuccessPayment()
{
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('lillyloverofwar-facilitator_api1.gmail.com');
$gateway->setPassword('U6LM3SG2MNCA3QE2');
$gateway->setSignature('AJVP9tUtdotIeVt82RpcG7n9ld-tAdCG1Ramb1u8yZECHhSpiXc0BO04');
$gateway->setTestMode(true);
$params = Session::get('params');
$response = $gateway->completePurchase($params)->send();
$paypalResponse = $response->getData(); // this is the raw response object
if(isset($paypalResponse['PAYMENTINFO_0_ACK']) && $paypalResponse['PAYMENTINFO_0_ACK'] === 'Success') {
// return View::make('successfulPayment')->with($params);
// Session::flush();
// Response
// print_r($paypalResponse);
} else {
//Failed transaction
}
// FLUSHING SESSION HERE GETS AN ERROR
// Session::flush();
return View::make('successfulPayment');
}
1) I get this error when I try (call_user_func_array() expects parameter 1 to be a valid callback, class 'Omnipay\Common\GatewayFactory' does not have a method 'creditCard').
You can't use credit cards on the PayPal Express gateway, only on Pro or REST. I recommend that you use the REST gateway not the Pro gateway (REST supersedes Pro and has more features).
I don't want to enter all the credit card details - Just speed the process up by entering the User's Name, Adress etc...
There is no need to do that if you are using PayPal Express anyway, because PayPal will provide you the necessary details after the user has gone through the PayPal login process and authorized the transaction.
Also I tried changing to Paypal_Pro and it didn't work. (same error as above) I changed config plus gateways in my payment controller.
2)How do you change PayPal_Express to PayPay_Pro?
I suggest you have a look at my fork of the omnipay-paypal gateway, https://github.com/delatbabel/omnipay-paypal -- on the accept-paypal-payments branch there are additional commits (sent as a PR to the main repository but not merged yet) with additional features such as using the REST gateway for either Credit Card or PayPal purchases, and additional API documentation including code examples on how to use the REST gateway.
Here is the code example for using the Rest gateway for a purchase transaction with a credit card:
// Create a gateway for the PayPal RestGateway
// (routes to GatewayFactory::create)
$gateway = Omnipay::create('RestGateway');
// Initialise the gateway
$gateway->initialize(array(
'clientId' => 'MyPayPalClientId',
'secret' => 'MyPayPalSecret',
'testMode' => true, // Or false when you are ready for live transactions
));
// Create a credit card object
// DO NOT USE THESE CARD VALUES -- substitute your own
// see the documentation in the class header.
$card = new CreditCard(array(
'firstName' => 'Example',
'lastName' => 'User',
'number' => '4111111111111111',
'expiryMonth' => '01',
'expiryYear' => '2020',
'cvv' => '123',
'billingAddress1' => '1 Scrubby Creek Road',
'billingCountry' => 'AU',
'billingCity' => 'Scrubby Creek',
'billingPostcode' => '4999',
'billingState' => 'QLD',
));
// Do a purchase transaction on the gateway
$transaction = $gateway->purchase(array(
'amount' => '10.00',
'currency' => 'AUD',
'description' => 'This is a test purchase transaction.',
'card' => $card,
));
$response = $transaction->send();
if ($response->isSuccessful()) {
echo "Purchase transaction was successful!\n";
$sale_id = $response->getTransactionReference();
echo "Transaction reference = " . $sale_id . "\n";
}

Omnipay 3Dsecure redirect

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.

Omnipay with Paypal Express

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.

How to use a variable as the amount for recurring payments (Paypal API)

I'm using the Paypal API to create a subscription system where there are two types of subscriptions
Monthly subscription (5dlls)
Annual subscription (50dlls)
I currently have the following code:
For setting the checkout:
public function do_purchase($type){
$this->load->library('paypal');
$requestParams = array(
'RETURNURL' => site_url('restaurant/get_purchase_details'),
'CANCELURL' => site_url('restaurant/afiliaturestaurante')
);
$orderParams = array(
'L_BILLINGTYPE0' => 'RecurringPayments',
'L_BILLINGAGREEMENTDESCRIPTION0' => 'Monthly',
'AMT' => 0
);
$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams);
if(is_array($response) && $response['ACK'] == 'Success') { //Request successful
$token = $response['TOKEN'];
header( 'Location: https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) );
}
}
For creating the recurring Paypal profile:
public function get_purchase_details(){
if( isset($_GET['token']) && !empty($_GET['token']) ) { // Token parameter exists
// Get checkout details, including buyer information.
// We can save it for future reference or cross-check with the data we have
$this->load->library('paypal');
$paypal = new Paypal();
$checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));
// Complete the checkout transaction
$requestParams = array(
'TOKEN' => $_GET['token'],
'PAYERID' => $checkoutDetails['PAYERID'],
'PROFILESTARTDATE' => '2014-03-7T05:38:48Z',
'DESC' => 'Monthly',
'BILLINGPERIOD' => 'Month',
'BILLINGFREQUENCY' => '1',
'AMT' => '5',
'CURRENCYCODE' => 'USD',
'COUNTRYCODE' => 'US',
'MAXFAILEDPAYMENTS' => '3',
);
$response = $paypal -> request('CreateRecurringPaymentsProfile',$requestParams);
if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
// We'll fetch the transaction ID for internal bookkeeping
$profileID = $response['PROFILEID'];
}
}
}
I need to use $type variable on get_purchase_details for setting the amount of the profile, how can I pass the variable through Paypal so I can user on the other function? I'm using a Paypal library for creating the cURL requests.
Thanks in advance
You could just set the value of $type in a session variable, and that would be available upon return from PayPal.
Alternatively, you could pass your $type value in the CUSTOM parameter of SetExpressCheckout and that way it'll be returned in the GetExpressCheckoutDetails response.

Categories