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))
|
->withHeaders($this->getHeaders($headers))
|
||||||
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
||||||
|
|
||||||
if($r->successful()) {
|
if($r->status() <= 422){
|
||||||
|
// if($r->successful()) {
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlog($r->body());
|
||||||
|
nlog($r->json());
|
||||||
|
nlog($r);
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
['response' => $r->body()],
|
['response' => $r->body()],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
@ -357,8 +362,21 @@ class PayPalBasePaymentDriver extends BaseDriver
|
|||||||
$this->client->company ?? $this->company_gateway->company,
|
$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
|
public function getHeaders(array $headers = []): array
|
||||||
{
|
{
|
||||||
|
|
||||||
return array_merge([
|
return array_merge([
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
'Content-type' => 'application/json',
|
'Content-type' => 'application/json',
|
||||||
|
@ -146,6 +146,12 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderID}/capture", 'post', ['body' => '']);
|
$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) {
|
} catch(\Exception $e) {
|
||||||
|
|
||||||
//Rescue for duplicate invoice_id
|
//Rescue for duplicate invoice_id
|
||||||
@ -192,8 +198,10 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
|||||||
$this->client,
|
$this->client,
|
||||||
$this->client->company,
|
$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 {
|
} else {
|
||||||
|
|
||||||
@ -212,7 +220,9 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
|||||||
|
|
||||||
$message = $response['body']['details'][0]['description'] ?? 'Payment failed. Please try again.';
|
$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']);
|
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
|
||||||
$response = json_decode($request['gateway_response'], true);
|
$response = json_decode($request['gateway_response'], true);
|
||||||
|
|
||||||
|
nlog($response);
|
||||||
|
|
||||||
if($request->has('token') && strlen($request->input('token')) > 2)
|
if($request->has('token') && strlen($request->input('token')) > 2)
|
||||||
return $this->processTokenPayment($request, $response);
|
return $this->processTokenPayment($request, $response);
|
||||||
|
|
||||||
@ -93,7 +95,14 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
|||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderID}/capture", 'post', ['body' => '']);
|
$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) {
|
catch(\Exception $e) {
|
||||||
|
|
||||||
@ -146,7 +155,9 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
|||||||
|
|
||||||
$message = $response['body']['details'][0]['description'] ?? 'Payment failed. Please try again.';
|
$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,
|
$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']))
|
if(isset($data['payment_source']))
|
||||||
$order['payment_source'] = $data['payment_source'];
|
$order['payment_source'] = $data['payment_source'];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
||||||
|
|
||||||
|
nlog($r->json());
|
||||||
return $r->json()['id'];
|
return $r->json()['id'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -4588,16 +4588,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "horstoeko/zugferd",
|
"name": "horstoeko/zugferd",
|
||||||
"version": "v1.0.45",
|
"version": "v1.0.47",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/horstoeko/zugferd.git",
|
"url": "https://github.com/horstoeko/zugferd.git",
|
||||||
"reference": "b778941ebe5b262061443e375e2f6f46bf2a7cec"
|
"reference": "7a5a8b7bb44f7aebfd66af112662c30383f31dd9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/b778941ebe5b262061443e375e2f6f46bf2a7cec",
|
"url": "https://api.github.com/repos/horstoeko/zugferd/zipball/7a5a8b7bb44f7aebfd66af112662c30383f31dd9",
|
||||||
"reference": "b778941ebe5b262061443e375e2f6f46bf2a7cec",
|
"reference": "7a5a8b7bb44f7aebfd66af112662c30383f31dd9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -4657,9 +4657,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/horstoeko/zugferd/issues",
|
"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",
|
"name": "http-interop/http-factory-guzzle",
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
@push('footer')
|
@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>
|
<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>
|
<script>
|
||||||
|
|
||||||
//&buyer-country=US¤cy=USD&enable-funding=venmo
|
//&buyer-country=US¤cy=USD&enable-funding=venmo
|
||||||
@ -44,19 +44,60 @@
|
|||||||
},
|
},
|
||||||
onApprove: function(data, actions) {
|
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)) {
|
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("gateway_response").value =JSON.stringify( data );
|
||||||
document.getElementById("server_response").submit();
|
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() {
|
onCancel: function() {
|
||||||
window.location.href = "/client/invoices/";
|
window.location.href = "/client/invoices/";
|
||||||
},
|
},
|
||||||
onError: function(error) {
|
onError: function(error) {
|
||||||
|
|
||||||
|
console.log("on error");
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
document.getElementById("gateway_response").value = error;
|
document.getElementById("gateway_response").value = error;
|
||||||
document.getElementById("server_response").submit();
|
document.getElementById("server_response").submit();
|
||||||
},
|
},
|
||||||
@ -64,6 +105,12 @@
|
|||||||
|
|
||||||
if(fundingSource != 'card')
|
if(fundingSource != 'card')
|
||||||
document.getElementById('paypal-button-container').hidden = true;
|
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) {
|
}).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');
|
let storeCard = document.querySelector('input[name=token-billing-checkbox]:checked');
|
||||||
|
|
||||||
@ -136,9 +132,44 @@
|
|||||||
document.getElementById("store_card").value = storeCard.value;
|
document.getElementById("store_card").value = storeCard.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("gateway_response").value = JSON.stringify( data );
|
document.getElementById("gateway_response").value =JSON.stringify( data );
|
||||||
document.getElementById("server_response").submit();
|
|
||||||
|
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() {
|
onCancel: function() {
|
||||||
@ -160,8 +191,8 @@
|
|||||||
// Render each field after checking for eligibility
|
// Render each field after checking for eligibility
|
||||||
if (cardField.isEligible()) {
|
if (cardField.isEligible()) {
|
||||||
|
|
||||||
const nameField = cardField.NameField();
|
// const nameField = cardField.NameField();
|
||||||
nameField.render("#card-name-field-container");
|
// nameField.render("#card-name-field-container");
|
||||||
|
|
||||||
const numberField = cardField.NumberField({
|
const numberField = cardField.NumberField({
|
||||||
inputEvents: {
|
inputEvents: {
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
@push('footer')
|
@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>
|
<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>
|
<script>
|
||||||
|
|
||||||
//&buyer-country=US¤cy=USD&enable-funding=venmo
|
//&buyer-country=US¤cy=USD&enable-funding=venmo
|
||||||
@ -43,13 +42,48 @@
|
|||||||
},
|
},
|
||||||
onApprove: function(data, actions) {
|
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)) {
|
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("gateway_response").value =JSON.stringify( data );
|
||||||
document.getElementById("server_response").submit();
|
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() {
|
onCancel: function() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user