mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Refactor for paypal implementation
This commit is contained in:
parent
673eaaf3e5
commit
9180dc4478
@ -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',
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
12
composer.lock
generated
@ -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",
|
||||
|
@ -26,7 +26,7 @@
|
||||
@push('footer')
|
||||
|
||||
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}¤cy={!! $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¤cy=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) {
|
||||
|
@ -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: {
|
||||
|
@ -26,7 +26,6 @@
|
||||
@push('footer')
|
||||
|
||||
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}¤cy={!! $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¤cy=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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user