Refactor for paypal implementation

This commit is contained in:
David Bomba 2024-05-24 10:38:07 +10:00
parent 673eaaf3e5
commit 9180dc4478
7 changed files with 181 additions and 28 deletions

View File

@ -344,10 +344,15 @@ class PayPalBasePaymentDriver extends BaseDriver
->withHeaders($this->getHeaders($headers))
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
if($r->successful()) {
if($r->status() <= 422){
// if($r->successful()) {
return $r;
}
nlog($r->body());
nlog($r->json());
nlog($r);
SystemLogger::dispatch(
['response' => $r->body()],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
@ -357,8 +362,21 @@ class PayPalBasePaymentDriver extends BaseDriver
$this->client->company ?? $this->company_gateway->company,
);
throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
return response()->json(['message' => "Gateway failure - {$r->body()}"], 401);
// throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
}
public function handleRetry($response, $request) {
// $response = $r->json();
// nlog($response['details']);
// if(in_array($response['details'][0]['issue'], ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED']))
return response()->json($response->json());
}
/**
@ -369,6 +387,7 @@ class PayPalBasePaymentDriver extends BaseDriver
*/
public function getHeaders(array $headers = []): array
{
return array_merge([
'Accept' => 'application/json',
'Content-type' => 'application/json',

View File

@ -146,6 +146,12 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
try {
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderID}/capture", 'post', ['body' => '']);
if($r->status() == 422) {
//handle conditions where the client may need to try again.
return $this->handleRetry($r, $request);
}
} catch(\Exception $e) {
//Rescue for duplicate invoice_id
@ -192,8 +198,10 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
$this->client,
$this->client->company,
);
return response()->json(['redirect' => route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)], false)]);
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
// return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
} else {
@ -212,7 +220,9 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
$message = $response['body']['details'][0]['description'] ?? 'Payment failed. Please try again.';
throw new PaymentFailed($message, 400);
return response()->json(['message' => $message], 400);
// throw new PaymentFailed($message, 400);
}
}

View File

@ -66,6 +66,8 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
$response = json_decode($request['gateway_response'], true);
nlog($response);
if($request->has('token') && strlen($request->input('token')) > 2)
return $this->processTokenPayment($request, $response);
@ -93,7 +95,14 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
}
try{
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderID}/capture", 'post', ['body' => '']);
if($r->status() == 422){
//handle conditions where the client may need to try again.
return $this->handleRetry($r, $request);
}
}
catch(\Exception $e) {
@ -146,7 +155,9 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
$message = $response['body']['details'][0]['description'] ?? 'Payment failed. Please try again.';
throw new PaymentFailed($message, 400);
return response()->json(['message' => $message], 400);
//throw new PaymentFailed($message, 400);
}
}
@ -202,7 +213,9 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
$this->client->company,
);
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
return response()->json(['redirect' => route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)], false)]);
// return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
}
@ -257,10 +270,9 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
if(isset($data['payment_source']))
$order['payment_source'] = $data['payment_source'];
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
nlog($r->json());
return $r->json()['id'];
}

12
composer.lock generated
View File

@ -4588,16 +4588,16 @@
},
{
"name": "horstoeko/zugferd",
"version": "v1.0.45",
"version": "v1.0.47",
"source": {
"type": "git",
"url": "https://github.com/horstoeko/zugferd.git",
"reference": "b778941ebe5b262061443e375e2f6f46bf2a7cec"
"reference": "7a5a8b7bb44f7aebfd66af112662c30383f31dd9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/b778941ebe5b262061443e375e2f6f46bf2a7cec",
"reference": "b778941ebe5b262061443e375e2f6f46bf2a7cec",
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/7a5a8b7bb44f7aebfd66af112662c30383f31dd9",
"reference": "7a5a8b7bb44f7aebfd66af112662c30383f31dd9",
"shasum": ""
},
"require": {
@ -4657,9 +4657,9 @@
],
"support": {
"issues": "https://github.com/horstoeko/zugferd/issues",
"source": "https://github.com/horstoeko/zugferd/tree/v1.0.45"
"source": "https://github.com/horstoeko/zugferd/tree/v1.0.47"
},
"time": "2024-05-21T14:57:41+00:00"
"time": "2024-05-23T03:12:53+00:00"
},
{
"name": "http-interop/http-factory-guzzle",

View File

@ -26,7 +26,7 @@
@push('footer')
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&currency={!! $currency !!}&components=buttons,funding-eligibility&intent=capture&enable-funding={!! $funding_source !!}" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
<div id="paypal-button-container"></div>
<script>
//&buyer-country=US&currency=USD&enable-funding=venmo
@ -44,19 +44,60 @@
},
onApprove: function(data, actions) {
var errorDetail = Array.isArray(data.details) && data.details[0];
console.log(data);
document.getElementById("gateway_response").value =JSON.stringify( data );
formData = JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server_response")))),
fetch('{{ route('client.payments.response') }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
},
body: formData,
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json(); // or response.json() if the response is JSON
})
.then(data => {
var errorDetail = Array.isArray(data.details) && data.details[0];
if (errorDetail && ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED'].includes(errorDetail.issue)) {
return actions.restart();
}
if(data.redirect){
window.location.href = data.redirect;
return;
}
document.getElementById("gateway_response").value =JSON.stringify( data );
document.getElementById("server_response").submit();
})
.catch(error => {
console.error('Error:', error);
document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`;
document.getElementById('errors').hidden = false;
});
},
onCancel: function() {
window.location.href = "/client/invoices/";
},
onError: function(error) {
console.log("on error");
console.log(error);
document.getElementById("gateway_response").value = error;
document.getElementById("server_response").submit();
},
@ -64,6 +105,12 @@
if(fundingSource != 'card')
document.getElementById('paypal-button-container').hidden = true;
document.querySelector('div[data-ref="required-fields-container').classList.add('hidden');
},
onInit: function (){
console.log("init");
}
}).render('#paypal-button-container').catch(function(err) {

View File

@ -125,10 +125,6 @@
}
var errorDetail = Array.isArray(data.details) && data.details[0];
if (errorDetail && ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED'].includes(errorDetail.issue)) {
return actions.restart();
}
let storeCard = document.querySelector('input[name=token-billing-checkbox]:checked');
@ -136,9 +132,44 @@
document.getElementById("store_card").value = storeCard.value;
}
document.getElementById("gateway_response").value = JSON.stringify( data );
document.getElementById("server_response").submit();
document.getElementById("gateway_response").value =JSON.stringify( data );
formData = JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server_response")))),
fetch('{{ route('client.payments.response') }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
},
body: formData,
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
var errorDetail = Array.isArray(data.details) && data.details[0];
if (errorDetail && ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED'].includes(errorDetail.issue)) {
return actions.restart();
}
if(data.redirect){
window.location.href = data.redirect;
return;
}
document.getElementById("gateway_response").value =JSON.stringify( data );
document.getElementById("server_response").submit();
})
.catch(error => {
console.error('Error:', error);
});
},
onCancel: function() {
@ -160,8 +191,8 @@
// Render each field after checking for eligibility
if (cardField.isEligible()) {
const nameField = cardField.NameField();
nameField.render("#card-name-field-container");
// const nameField = cardField.NameField();
// nameField.render("#card-name-field-container");
const numberField = cardField.NumberField({
inputEvents: {

View File

@ -26,7 +26,6 @@
@push('footer')
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&currency={!! $currency !!}&merchant-id={!! $merchantId !!}&components=buttons,funding-eligibility&intent=capture&enable-funding={!! $funding_source !!}" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
<div id="paypal-button-container"></div>
<script>
//&buyer-country=US&currency=USD&enable-funding=venmo
@ -43,13 +42,48 @@
},
onApprove: function(data, actions) {
var errorDetail = Array.isArray(data.details) && data.details[0];
document.getElementById("gateway_response").value =JSON.stringify( data );
formData = JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server_response")))),
fetch('{{ route('client.payments.response') }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
},
body: formData,
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
var errorDetail = Array.isArray(data.details) && data.details[0];
if (errorDetail && ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED'].includes(errorDetail.issue)) {
return actions.restart();
}
return actions.restart();
}
if(data.redirect){
window.location.href = data.redirect;
return;
}
document.getElementById("gateway_response").value =JSON.stringify( data );
document.getElementById("server_response").submit();
})
.catch(error => {
console.error('Error:', error);
document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`;
document.getElementById('errors').hidden = false;
});
},
onCancel: function() {