mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 06:14:36 -04:00
Fixes for text body templates
This commit is contained in:
parent
de853b3445
commit
d23866932b
@ -126,7 +126,7 @@ class BaseEmailEngine implements EngineInterface
|
||||
|
||||
if (! empty($this->variables)) {
|
||||
|
||||
$text = str_replace(['$paymentLink', '$viewButton', '$view_button', '$viewLink', '$view_link'], '$view_url', $text);
|
||||
$text = str_replace(['$paymentLink', '$viewButton', '$view_button', '$viewLink', '$view_link'], "\r\n\r\n".'$view_url'."\r\n", $text);
|
||||
$text = str_replace(array_keys($this->variables), array_values($this->variables), $text);
|
||||
$text = str_replace(array_keys($this->variables), array_values($this->variables), $text);
|
||||
|
||||
|
@ -16,6 +16,7 @@ use Carbon\Carbon;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
@ -30,6 +31,8 @@ class PayPalBasePaymentDriver extends BaseDriver
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public string $risk_guid;
|
||||
|
||||
public $token_billing = true;
|
||||
|
||||
public $can_authorise_credit_card = false;
|
||||
@ -106,6 +109,7 @@ class PayPalBasePaymentDriver extends BaseDriver
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->risk_guid = Str::random(32);
|
||||
|
||||
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
|
||||
|
||||
@ -432,6 +436,7 @@ class PayPalBasePaymentDriver extends BaseDriver
|
||||
'Accept-Language' => 'en_US',
|
||||
'PayPal-Partner-Attribution-Id' => 'invoiceninja_SP_PPCP',
|
||||
'PayPal-Request-Id' => Str::uuid()->toString(),
|
||||
'PAYPAL-CLIENT-METADATA-ID' => $this->risk_guid,
|
||||
], $headers);
|
||||
}
|
||||
|
||||
@ -479,5 +484,5 @@ class PayPalBasePaymentDriver extends BaseDriver
|
||||
|
||||
PayPalWebhook::dispatch($request->all(), $request->headers->all(), $this->access_token);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,6 +16,7 @@ use Carbon\Carbon;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
@ -84,6 +85,7 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
||||
*/
|
||||
public function processPaymentView($data)
|
||||
{
|
||||
|
||||
$this->init()->checkPaymentsReceivable();
|
||||
|
||||
$data['gateway'] = $this;
|
||||
@ -97,6 +99,7 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
||||
$data['gateway_type_id'] = $this->gateway_type_id;
|
||||
$data['merchantId'] = $this->company_gateway->getConfigField('merchantId');
|
||||
$data['currency'] = $this->client->currency()->code;
|
||||
$data['guid'] = $this->risk_guid;
|
||||
|
||||
if($this->gateway_type_id == 29)
|
||||
return render('gateways.paypal.ppcp.card', $data);
|
||||
@ -109,7 +112,6 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
||||
* Processes the payment response
|
||||
*
|
||||
* @param mixed $request
|
||||
* @return void
|
||||
*/
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
@ -366,4 +368,73 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
|
||||
}
|
||||
|
||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||
{
|
||||
$data = [];
|
||||
$this->payment_hash = $payment_hash;
|
||||
|
||||
$data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee;
|
||||
$data["payment_source"] = [
|
||||
"card" => [
|
||||
"vault_id" => $cgt->token,
|
||||
"stored_credential" => [
|
||||
"payment_initiator" => "MERCHANT",
|
||||
"payment_type" => "UNSCHEDULED",
|
||||
"usage" => "SUBSEQUENT",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$orderId = $this->createOrder($data);
|
||||
|
||||
$r = false;
|
||||
|
||||
try {
|
||||
|
||||
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderId}", 'get', ['body' => '']);
|
||||
|
||||
if($r->status() == 422) {
|
||||
//handle conditions where the client may need to try again.
|
||||
|
||||
$r = $this->handleDuplicateInvoiceId($orderId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
} catch(\Exception $e) {
|
||||
|
||||
//Rescue for duplicate invoice_id
|
||||
if(stripos($e->getMessage(), 'DUPLICATE_INVOICE_ID') !== false) {
|
||||
|
||||
|
||||
$r = $this->handleDuplicateInvoiceId($orderId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$response = $r->json();
|
||||
|
||||
$data = [
|
||||
'payment_type' => $this->getPaymentMethod((string)$cgt->gateway_type_id),
|
||||
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
||||
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
||||
'gateway_type_id' => $this->gateway_type_id,
|
||||
];
|
||||
|
||||
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => $response, 'data' => $data],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_PAYPAL_PPCP,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -20,6 +20,7 @@ use App\Jobs\Util\SystemLogger;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use App\Models\ClientGatewayToken;
|
||||
use App\Models\PaymentHash;
|
||||
use App\PaymentDrivers\PayPal\PayPalBasePaymentDriver;
|
||||
|
||||
class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
@ -30,6 +31,7 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
|
||||
public function processPaymentView($data)
|
||||
{
|
||||
|
||||
$this->init();
|
||||
|
||||
$data['gateway'] = $this;
|
||||
@ -43,6 +45,7 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
$data['funding_source'] = $this->paypal_payment_method;
|
||||
$data['gateway_type_id'] = $this->gateway_type_id;
|
||||
$data['currency'] = $this->client->currency()->code;
|
||||
$data['guid'] = $this->risk_guid;
|
||||
|
||||
if($this->gateway_type_id == 29)
|
||||
return render('gateways.paypal.ppcp.card', $data);
|
||||
@ -56,7 +59,6 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
* processPaymentResponse
|
||||
*
|
||||
* @param mixed $request
|
||||
* @return void
|
||||
*/
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
@ -291,7 +293,6 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
*
|
||||
* @param mixed $request
|
||||
* @param array $response
|
||||
* @return void
|
||||
*/
|
||||
public function processTokenPayment($request, array $response) {
|
||||
|
||||
@ -342,4 +343,72 @@ class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
|
||||
}
|
||||
|
||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||
{
|
||||
$data = [];
|
||||
$this->payment_hash = $payment_hash;
|
||||
|
||||
$data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee;
|
||||
$data["payment_source"] = [
|
||||
"card" => [
|
||||
"vault_id" => $cgt->token,
|
||||
"stored_credential" => [
|
||||
"payment_initiator" => "MERCHANT",
|
||||
"payment_type" => "UNSCHEDULED",
|
||||
"usage" => "SUBSEQUENT",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$orderId = $this->createOrder($data);
|
||||
|
||||
$r = false;
|
||||
|
||||
try {
|
||||
|
||||
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderId}", 'get', ['body' => '']);
|
||||
|
||||
if($r->status() == 422) {
|
||||
//handle conditions where the client may need to try again.
|
||||
|
||||
$r = $this->handleDuplicateInvoiceId($orderId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
} catch(\Exception $e) {
|
||||
|
||||
//Rescue for duplicate invoice_id
|
||||
if(stripos($e->getMessage(), 'DUPLICATE_INVOICE_ID') !== false) {
|
||||
|
||||
|
||||
$r = $this->handleDuplicateInvoiceId($orderId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$response = $r->json();
|
||||
|
||||
$data = [
|
||||
'payment_type' => $this->getPaymentMethod((string)$cgt->gateway_type_id),
|
||||
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
||||
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
||||
'gateway_type_id' => $this->gateway_type_id,
|
||||
];
|
||||
|
||||
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => $response, 'data' => $data],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_PAYPAL_PPCP,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ class EmailDefaults
|
||||
$breaks = ["<br />","<br>","<br/>"];
|
||||
$this->email->email_object->text_body = str_ireplace($breaks, "\r\n", $this->email->email_object->body);
|
||||
$this->email->email_object->text_body = strip_tags($this->email->email_object->text_body);
|
||||
$this->email->email_object->text_body = str_replace(['$view_button','$viewButton'], '$view_url', $this->email->email_object->text_body);
|
||||
$this->email->email_object->text_body = str_replace(['$view_button','$viewButton'], "\r\n\r\n".'$view_url'."\r\n", $this->email->email_object->text_body);
|
||||
|
||||
if ($this->template == 'email.template.custom') {
|
||||
$this->email->email_object->body = (str_replace('$body', $this->email->email_object->body, str_replace(["\r","\n"], "", $this->email->email_object->settings->email_style_custom)));
|
||||
|
@ -29,6 +29,17 @@
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
|
||||
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">
|
||||
{
|
||||
"f":"{{ $guid }}",
|
||||
"s":"paypal.pay" // unique ID for each web page
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://c.paypal.com/da/r/fb.js"></script>
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
.loader {
|
||||
width: 48px;
|
||||
|
@ -75,6 +75,14 @@
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">
|
||||
{
|
||||
"f":"{{ $guid }}",
|
||||
"s":"paypal.card" // unique ID for each web page
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://c.paypal.com/da/r/fb.js"></script>
|
||||
|
||||
@if(isset($merchantId))
|
||||
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&merchantId={!! $merchantId !!}&components=card-fields" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
|
||||
@ -150,6 +158,10 @@
|
||||
})
|
||||
.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;
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
@ -157,12 +169,20 @@
|
||||
|
||||
window.location.href = "/client/invoices/";
|
||||
},
|
||||
onError: function(error) {
|
||||
// onError: function(error) {
|
||||
|
||||
document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`;
|
||||
document.getElementById('errors').hidden = false;
|
||||
|
||||
},
|
||||
// console.log("submit catch");
|
||||
// const errorM = parseError(error);
|
||||
|
||||
// console.log(errorM);
|
||||
|
||||
// const msg = handle422Error(errorM);
|
||||
|
||||
// document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${msg.description}`;
|
||||
// document.getElementById('errors').hidden = false;
|
||||
|
||||
// },
|
||||
onClick: function (){
|
||||
|
||||
}
|
||||
@ -213,10 +233,18 @@
|
||||
|
||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||
|
||||
cardField.submit().then((response) => {
|
||||
cardField.submit().then(() => {
|
||||
|
||||
}).catch((error) => {
|
||||
|
||||
let msg;
|
||||
|
||||
if(!['INVALID_NUMBER','INVALID_CVV','INVALID_EXPIRY'].includes(error.message))
|
||||
{
|
||||
const errorM = parseError(error.message);
|
||||
msg = handle422Error(errorM);
|
||||
}
|
||||
|
||||
document.getElementById('pay-now').disabled = false;
|
||||
document.querySelector('#pay-now > svg').classList.add('hidden');
|
||||
document.querySelector('#pay-now > span').classList.remove('hidden');
|
||||
@ -230,7 +258,9 @@
|
||||
else if(error.message == 'INVALID_EXPIRY') {
|
||||
document.getElementById('errors').textContent = "{{ ctrans('texts.invalid_cvv') }}";
|
||||
}
|
||||
|
||||
else if(msg.description){
|
||||
document.getElementById('errors').textContent = msg?.description;
|
||||
}
|
||||
document.getElementById('errors').hidden = false;
|
||||
|
||||
});
|
||||
@ -242,6 +272,39 @@
|
||||
|
||||
}
|
||||
|
||||
function handle422Error(errorData) {
|
||||
const errorDetails = errorData.details || [];
|
||||
const detail = errorDetails[0];
|
||||
return detail;
|
||||
}
|
||||
|
||||
|
||||
function parseError(errorMessage)
|
||||
{
|
||||
try {
|
||||
JSON.parse(errorMessage);
|
||||
return errorMessage;
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
|
||||
const startIndex = errorMessage.indexOf('{');
|
||||
const endIndex = errorMessage.lastIndexOf('}');
|
||||
|
||||
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
||||
const jsonString = errorMessage.substring(startIndex, endIndex + 1);
|
||||
try {
|
||||
const json = JSON.parse(jsonString);
|
||||
return json;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@ -266,7 +329,6 @@
|
||||
if (payWithCreditCardToggle) {
|
||||
payWithCreditCardToggle
|
||||
.addEventListener('click', () => {
|
||||
console.log("Cc");
|
||||
document
|
||||
.getElementById('save-card--container').style.display = 'grid';
|
||||
document
|
||||
|
@ -25,6 +25,16 @@
|
||||
|
||||
@push('footer')
|
||||
|
||||
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">
|
||||
{
|
||||
"f":"{{ $guid }}",
|
||||
"s":"paypal.ppcp.pay" // unique ID for each web page
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://c.paypal.com/da/r/fb.js"></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>
|
||||
<script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user