mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
paypal rest
This commit is contained in:
commit
d411704d89
@ -711,6 +711,29 @@ class CreateSingleAccount extends Command
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
if (config('ninja.testvars.paypal_rest') && ($this->gateway == 'all' || $this->gateway == 'paypal_rest')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
$cg->user_id = $user->id;
|
||||
$cg->gateway_key = '80af24a6a691230bbec33e930ab40665';
|
||||
$cg->require_cvv = true;
|
||||
$cg->require_billing_address = true;
|
||||
$cg->require_shipping_address = true;
|
||||
$cg->update_details = true;
|
||||
$cg->config = encrypt(config('ninja.testvars.paypal_rest'));
|
||||
$cg->save();
|
||||
|
||||
$gateway_types = $cg->driver()->gatewayTypes();
|
||||
|
||||
$fees_and_limits = new stdClass;
|
||||
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
|
||||
|
||||
$cg->fees_and_limits = $fees_and_limits;
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (config('ninja.testvars.checkout') && ($this->gateway == 'all' || $this->gateway == 'checkout')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
|
@ -190,6 +190,20 @@ class Gateway extends StaticModel
|
||||
GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], // Forte
|
||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']],
|
||||
];
|
||||
case 60:
|
||||
return [
|
||||
GatewayType::PAYPAL => ['refund' => false, 'token_billing' => false],
|
||||
GatewayType::CREDIT_CARD => ['refund' => false, 'token_billing' => false],
|
||||
GatewayType::VENMO => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::SEPA => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::BANCONTACT => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::EPS => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::MYBANK => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::PAYLATER => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::PRZELEWY24 => ['refund' => false, 'token_billing' => false],
|
||||
// GatewayType::SOFORT => ['refund' => false, 'token_billing' => false],
|
||||
]; //Paypal
|
||||
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
@ -29,17 +29,6 @@ namespace App\Models;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|GatewayType whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|GatewayType whereName($value)
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\PaymentType> $payment_methods
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class GatewayType extends StaticModel
|
||||
@ -94,6 +83,14 @@ class GatewayType extends StaticModel
|
||||
|
||||
const BACS = 24;
|
||||
|
||||
const VENMO = 25;
|
||||
|
||||
const MERCADOPAGO = 26;
|
||||
|
||||
const MYBANK = 27;
|
||||
|
||||
const PAYLATER = 28;
|
||||
|
||||
public function gateway()
|
||||
{
|
||||
return $this->belongsTo(Gateway::class);
|
||||
@ -153,9 +150,18 @@ class GatewayType extends StaticModel
|
||||
return ctrans('texts.fpx');
|
||||
case self::KLARNA:
|
||||
return ctrans('texts.klarna');
|
||||
case self::VENMO:
|
||||
return ctrans('texts.payment_type_Venmo');
|
||||
case self::MERCADOPAGO:
|
||||
return ctrans('texts.mercado_pago');
|
||||
case self::MYBANK:
|
||||
return ctrans('texts.mybank');
|
||||
case self::PAYLATER:
|
||||
return ctrans('texts.paypal_paylater');
|
||||
default:
|
||||
return ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@ class PaymentType extends StaticModel
|
||||
const BACS = 49;
|
||||
const STRIPE_BANK_TRANSFER = 50;
|
||||
const CASH_APP = 51;
|
||||
const VENMO = 25;
|
||||
|
||||
public array $type_names = [
|
||||
self::BANK_TRANSFER => 'payment_type_Bank Transfer',
|
||||
|
@ -88,7 +88,7 @@ class ClientObserver
|
||||
{
|
||||
|
||||
/** Monitor postal code changes for US based clients for tax calculations */
|
||||
if($client->getOriginal('postal_code') != $client->postal_code && $client->country_id == 840 && $client->company->calculate_taxes && !$client->company->account->isFreeHostedClient()) {
|
||||
if(($client->getOriginal('shipping_postal_code') != $client->shipping_postal_code || $client->getOriginal('postal_code') != $client->postal_code) && $client->country_id == 840 && $client->company->calculate_taxes && !$client->company->account->isFreeHostedClient()) {
|
||||
UpdateTaxData::dispatch($client, $client->company);
|
||||
}
|
||||
|
||||
|
432
app/PaymentDrivers/PayPalRestPaymentDriver.php
Normal file
432
app/PaymentDrivers/PayPalRestPaymentDriver.php
Normal file
@ -0,0 +1,432 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers;
|
||||
|
||||
use Omnipay\Omnipay;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentType;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class PayPalRestPaymentDriver extends BaseDriver
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public $token_billing = false;
|
||||
|
||||
public $can_authorise_credit_card = false;
|
||||
|
||||
private $omnipay_gateway;
|
||||
|
||||
private float $fee = 0;
|
||||
|
||||
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
||||
|
||||
private string $api_endpoint_url = '';
|
||||
|
||||
private string $paypal_payment_method = '';
|
||||
|
||||
private array $funding_options = [
|
||||
3 => 'paypal',
|
||||
1 => 'card',
|
||||
25 => 'venmo',
|
||||
9 => 'sepa',
|
||||
12 => 'bancontact',
|
||||
17 => 'eps',
|
||||
15 => 'giropay',
|
||||
13 => 'ideal',
|
||||
26 => 'mercadopago',
|
||||
27 => 'mybank',
|
||||
28 => 'paylater',
|
||||
16 => 'p24',
|
||||
7 => 'sofort'
|
||||
];
|
||||
|
||||
|
||||
public function gatewayTypes()
|
||||
{
|
||||
|
||||
$funding_options = [];
|
||||
|
||||
foreach ($this->company_gateway->fees_and_limits as $key => $value) {
|
||||
if ($value->is_enabled) {
|
||||
$funding_options[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $funding_options;
|
||||
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->omnipay_gateway = Omnipay::create(
|
||||
$this->company_gateway->gateway->provider
|
||||
);
|
||||
|
||||
$this->omnipay_gateway->initialize((array) $this->company_gateway->getConfig());
|
||||
|
||||
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPaymentMethod($payment_method_id)
|
||||
{
|
||||
if(!$payment_method_id)
|
||||
return $this;
|
||||
|
||||
$this->paypal_payment_method = $this->funding_options[$payment_method_id];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function authorizeView($payment_method)
|
||||
{
|
||||
// PayPal doesn't support direct authorization.
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function authorizeResponse($request)
|
||||
{
|
||||
// PayPal doesn't support direct authorization.
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function processPaymentView($data)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
$data['gateway'] = $this;
|
||||
|
||||
$this->payment_hash->data = array_merge((array) $this->payment_hash->data, ['amount' => $data['total']['amount_with_fee']]);
|
||||
$this->payment_hash->save();
|
||||
|
||||
$data['client_id'] = $this->company_gateway->getConfigField('clientId');
|
||||
$data['token'] = $this->getClientToken();
|
||||
$data['order_id'] = $this->createOrder($data);
|
||||
$data['funding_options'] = $this->paypal_payment_method;
|
||||
|
||||
return render('gateways.paypal.pay', $data);
|
||||
|
||||
}
|
||||
|
||||
private function getFundingOptions():string
|
||||
{
|
||||
|
||||
$enums = [
|
||||
3 => 'paypal',
|
||||
1 => 'card',
|
||||
25 => 'venmo',
|
||||
// 9 => 'sepa',
|
||||
// 12 => 'bancontact',
|
||||
// 17 => 'eps',
|
||||
// 15 => 'giropay',
|
||||
// 13 => 'ideal',
|
||||
// 26 => 'mercadopago',
|
||||
// 27 => 'mybank',
|
||||
// 28 => 'paylater',
|
||||
// 16 => 'p24',
|
||||
// 7 => 'sofort'
|
||||
];
|
||||
|
||||
$funding_options = '';
|
||||
|
||||
foreach($this->company_gateway->fees_and_limits as $key => $value) {
|
||||
|
||||
if($value->is_enabled) {
|
||||
|
||||
$funding_options .=$enums[$key].',';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rtrim($funding_options, ',');
|
||||
|
||||
}
|
||||
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
|
||||
$response = json_decode($request['gateway_response'], true);
|
||||
|
||||
if($response['status'] == 'COMPLETED' && isset($response['purchase_units'])){
|
||||
|
||||
$data = [
|
||||
'payment_type' => PaymentType::PAYPAL,
|
||||
'amount' => $response['purchase_units'][0]['amount']['value'],
|
||||
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
||||
'gateway_type_id' => GatewayType::PAYPAL,
|
||||
];
|
||||
|
||||
$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,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => $response],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_PAYPAL,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
|
||||
throw new PaymentFailed('Payment failed. Please try again.', 401);
|
||||
}
|
||||
}
|
||||
|
||||
private function getClientToken(): string
|
||||
{
|
||||
|
||||
$r = $this->gatewayRequest('/v1/identity/generate-token', 'post', ['body' => '']);
|
||||
|
||||
if($r->successful())
|
||||
return $r->json()['client_token'];
|
||||
|
||||
throw new PaymentFailed('Unable to gain client token from Paypal. Check your configuration', 401);
|
||||
|
||||
}
|
||||
|
||||
private function createOrder(array $data): string
|
||||
{
|
||||
|
||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||
|
||||
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||
|
||||
$order = [
|
||||
"intent" => "CAPTURE",
|
||||
"payer" => [
|
||||
"name" => [
|
||||
"given_name" => $this->client->present()->first_name(),
|
||||
"surname" => $this->client->present()->last_name(),
|
||||
],
|
||||
"email_address" => $this->client->present()->email(),
|
||||
"address" => [
|
||||
"address_line_1" => $this->client->address1,
|
||||
"address_line_2" => $this->client->address2,
|
||||
"admin_area_1" => $this->client->city,
|
||||
"admin_area_2" => $this->client->state,
|
||||
"postal_code" => $this->client->postal_code,
|
||||
"country_code" => $this->client->country->iso_3166_2,
|
||||
]
|
||||
],
|
||||
"purchase_units" => [
|
||||
[
|
||||
"description" =>ctrans('texts.invoice_number').'# '.$invoice->number,
|
||||
"invoice_id" => $invoice->number,
|
||||
"amount" => [
|
||||
"value" => (string)$data['amount_with_fee'],
|
||||
"currency_code"=> $this->client->currency()->code,
|
||||
"breakdown" => [
|
||||
"item_total" => [
|
||||
"currency_code" => $this->client->currency()->code,
|
||||
"value" => (string)$data['amount_with_fee']
|
||||
]
|
||||
]
|
||||
],
|
||||
"items"=> [
|
||||
[
|
||||
"name" => ctrans('texts.invoice_number').'# '.$invoice->number,
|
||||
"quantity" => "1",
|
||||
"unit_amount" => [
|
||||
"currency_code" => $this->client->currency()->code,
|
||||
"value" => (string)$data['amount_with_fee']
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
||||
|
||||
return $r->json()['id'];
|
||||
|
||||
}
|
||||
|
||||
public function gatewayRequest(string $uri, string $verb, array $data, ?array $headers = [])
|
||||
{
|
||||
$r = Http::withToken($this->omnipay_gateway->getToken())
|
||||
->withHeaders($this->getHeaders($headers))
|
||||
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
||||
|
||||
if($r->successful())
|
||||
return $r;
|
||||
|
||||
throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
|
||||
|
||||
}
|
||||
|
||||
private function getHeaders(array $headers = []): array
|
||||
{
|
||||
return array_merge([
|
||||
'Accept' => 'application/json',
|
||||
'Content-type' => 'application/json',
|
||||
'Accept-Language' => 'en_US',
|
||||
], $headers);
|
||||
}
|
||||
|
||||
/*
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
$this->initializeOmnipayGateway();
|
||||
|
||||
$response = $this->omnipay_gateway
|
||||
->completePurchase(['amount' => $this->payment_hash->data->amount, 'currency' => $this->client->getCurrencyCode()])
|
||||
->send();
|
||||
|
||||
if ($response->isCancelled() && $this->client->getSetting('enable_client_portal')) {
|
||||
return redirect()->route('client.invoices.index')->with('warning', ctrans('texts.status_cancelled'));
|
||||
} elseif ($response->isCancelled() && !$this->client->getSetting('enable_client_portal')) {
|
||||
redirect()->route('client.invoices.show', ['invoice' => $this->payment_hash->fee_invoice])->with('warning', ctrans('texts.status_cancelled'));
|
||||
}
|
||||
|
||||
if ($response->isSuccessful()) {
|
||||
$data = [
|
||||
'payment_method' => $response->getData()['TOKEN'],
|
||||
'payment_type' => PaymentType::PAYPAL,
|
||||
'amount' => $this->payment_hash->data->amount,
|
||||
'transaction_reference' => $response->getTransactionReference(),
|
||||
'gateway_type_id' => GatewayType::PAYPAL,
|
||||
];
|
||||
|
||||
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||
|
||||
SystemLogger::dispatch(
|
||||
['response' => (array) $response->getData(), 'data' => $data],
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_PAYPAL,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
if (! $response->isSuccessful()) {
|
||||
$data = $response->getData();
|
||||
|
||||
$this->sendFailureMail($response->getMessage() ?: '');
|
||||
|
||||
$message = [
|
||||
'server_response' => $data['L_LONGMESSAGE0'],
|
||||
'data' => $this->payment_hash->data,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$message,
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_PAYPAL,
|
||||
$this->client,
|
||||
$this->client->company,
|
||||
);
|
||||
|
||||
throw new PaymentFailed($response->getMessage(), $response->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public function generatePaymentDetails(array $data)
|
||||
{
|
||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||
|
||||
// $this->fee = $this->feeCalc($invoice, $data['total']['amount_with_fee']);
|
||||
|
||||
return [
|
||||
'currency' => $this->client->getCurrencyCode(),
|
||||
'transactionType' => 'Purchase',
|
||||
'clientIp' => request()->getClientIp(),
|
||||
// 'amount' => round(($data['total']['amount_with_fee'] + $this->fee),2),
|
||||
'amount' => round($data['total']['amount_with_fee'], 2),
|
||||
'returnUrl' => route('client.payments.response', [
|
||||
'company_gateway_id' => $this->company_gateway->id,
|
||||
'payment_hash' => $this->payment_hash->hash,
|
||||
'payment_method_id' => GatewayType::PAYPAL,
|
||||
]),
|
||||
'cancelUrl' => $this->client->company->domain()."/client/invoices/{$invoice->hashed_id}",
|
||||
'description' => implode(',', collect($this->payment_hash->data->invoices)
|
||||
->map(function ($invoice) {
|
||||
return sprintf('%s: %s', ctrans('texts.invoice_number'), $invoice->invoice_number);
|
||||
})->toArray()),
|
||||
'transactionId' => $this->payment_hash->hash.'-'.time(),
|
||||
'ButtonSource' => 'InvoiceNinja_SP',
|
||||
'solutionType' => 'Sole',
|
||||
];
|
||||
}
|
||||
|
||||
public function generatePaymentItems(array $data)
|
||||
{
|
||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||
|
||||
$items = [];
|
||||
|
||||
$items[] = new Item([
|
||||
'name' => ' ',
|
||||
'description' => ctrans('texts.invoice_number').'# '.$invoice->number,
|
||||
'price' => $data['total']['amount_with_fee'],
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
private function feeCalc($invoice, $invoice_total)
|
||||
{
|
||||
$invoice->service()->removeUnpaidGatewayFees();
|
||||
$invoice = $invoice->fresh();
|
||||
|
||||
$balance = floatval($invoice->balance);
|
||||
|
||||
$_updated_invoice = $invoice->service()->addGatewayFee($this->company_gateway, GatewayType::PAYPAL, $invoice_total)->save();
|
||||
|
||||
if (floatval($_updated_invoice->balance) > $balance) {
|
||||
$fee = floatval($_updated_invoice->balance) - $balance;
|
||||
|
||||
$this->payment_hash->fee_total = $fee;
|
||||
$this->payment_hash->save();
|
||||
|
||||
return $fee;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -68,6 +68,8 @@ trait Inviteable
|
||||
|
||||
$qr = $writer->writeString($this->getPaymentLink(), 'utf-8');
|
||||
|
||||
return "<div>$qr</div>";
|
||||
|
||||
return "<svg class='pqrcode' viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect x='0' y='0' width='100%' height='100%' />{$qr}</svg>";
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ return [
|
||||
'password' => 'password',
|
||||
'stripe' => env('STRIPE_KEYS', ''),
|
||||
'paypal' => env('PAYPAL_KEYS', ''),
|
||||
'paypal_rest' => env('PAYPAL_REST_KEYS', ''),
|
||||
'authorize' => env('AUTHORIZE_KEYS', ''),
|
||||
'checkout' => env('CHECKOUT_KEYS', ''),
|
||||
'travis' => env('TRAVIS', false),
|
||||
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Gateway;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
|
||||
if(!Gateway::find(60))
|
||||
{
|
||||
|
||||
$fields = new \stdClass;
|
||||
$fields->clientId = "";
|
||||
$fields->secret = "";
|
||||
$fields->testMode = false;
|
||||
|
||||
$paypal = new Gateway;
|
||||
$paypal->id = 60;
|
||||
$paypal->name = 'PayPal REST';
|
||||
$paypal->key = '80af24a6a691230bbec33e930ab40665';
|
||||
$paypal->provider = 'PayPal_Rest';
|
||||
$paypal->is_offsite = false;
|
||||
$paypal->fields = \json_encode($fields);
|
||||
$paypal->visible = 1;
|
||||
$paypal->site_url = 'https://www.paypal.com/';
|
||||
$paypal->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
@ -83,6 +83,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
['id' => 57, 'name' => 'Square', 'provider' => 'Square', 'is_offsite' => false, 'sort_order' => 21, 'key' => '65faab2ab6e3223dbe848b1686490baz', 'fields' => '{"accessToken":"","applicationId":"","locationId":"","testMode":false}'],
|
||||
['id' => 58, 'name' => 'Razorpay', 'provider' => 'Razorpay', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9', 'fields' => '{"apiKey":"","apiSecret":""}'],
|
||||
['id' => 59, 'name' => 'Forte', 'provider' => 'Forte', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'kivcvjexxvdiyqtj3mju5d6yhpeht2xs', 'fields' => '{"testMode":false,"apiLoginId":"","apiAccessId":"","secureKey":"","authOrganizationId":"","organizationId":"","locationId":""}'],
|
||||
['id' => 60, 'name' => 'PayPal REST', 'provider' => 'PayPal_Rest', 'key' => '80af24a6a691230bbec33e930ab40665', 'fields' => '{"clientId":"","secret":"","signature":"","testMode":false}'],
|
||||
];
|
||||
|
||||
foreach ($gateways as $gateway) {
|
||||
@ -99,7 +100,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
|
||||
Gateway::query()->update(['visible' => 0]);
|
||||
|
||||
Gateway::whereIn('id', [1,3,7,11,15,20,39,46,55,50,57,52,58,59])->update(['visible' => 1]);
|
||||
Gateway::whereIn('id', [1,3,7,11,15,20,39,46,55,50,57,52,58,59,60])->update(['visible' => 1]);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
Gateway::whereIn('id', [20])->update(['visible' => 0]);
|
||||
|
@ -5124,6 +5124,10 @@ $LANG = array(
|
||||
'income' => 'Income',
|
||||
'amount_received_help' => 'Enter a value here if the total amount received was MORE than the invoice amount, or when recording a payment with no invoices. Otherwise this field should be left blank.',
|
||||
'vendor_phone' => 'Vendor Phone',
|
||||
'mercado_pago' => 'Mercado Pago',
|
||||
'mybank' => 'MyBank',
|
||||
'paypal_paylater' => 'Pay in 4',
|
||||
'paid_date' => 'Paid Date',
|
||||
);
|
||||
|
||||
|
||||
|
@ -16,4 +16,4 @@ parameters:
|
||||
excludePaths:
|
||||
- 'vendor/'
|
||||
universalObjectCratesClasses:
|
||||
- App\DataMapper\Tax\RuleInterface
|
||||
- App\DataMapper\Tax\RuleInterface
|
||||
|
@ -0,0 +1,68 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => 'PayPal'])
|
||||
|
||||
@section('gateway_head')
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
|
||||
/>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server_response">
|
||||
@csrf
|
||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->company_gateway->id }}">
|
||||
<input type="hidden" name="gateway_response" id="gateway_response">
|
||||
<input type="hidden" name="amount_with_fee" id="amount_with_fee" value="{{ $total['amount_with_fee'] }}"/>
|
||||
</form>
|
||||
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
|
||||
<div id="paypal-button-container" class="paypal-button-container"></div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script src="https://www.paypal.com/sdk/js?buyer-country=US¤cy=USD&enable-funding={!! $funding_options !!}&disable-funding=credit&components=buttons,hosted-fields,funding-eligibility&intent=capture&client-id={!! $client_id !!}" data-client-token="{!! $token !!}">
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
paypal.Buttons({
|
||||
|
||||
env: "{{ $gateway->company_gateway->getConfigField('testMode') ? 'sandbox' : 'production' }}",
|
||||
client: {
|
||||
@if($gateway->company_gateway->getConfigField('testMode'))
|
||||
sandbox: "{{ $gateway->company_gateway->getConfigField('clientId') }}"
|
||||
@else
|
||||
production: "{{ $gateway->company_gateway->getConfigField('clientId') }}"
|
||||
@endif
|
||||
},
|
||||
createOrder: function(data, actions) {
|
||||
return "{!! $order_id !!}"
|
||||
},
|
||||
onApprove: function(data, actions) {
|
||||
|
||||
return actions.order.capture().then(function(details) {
|
||||
|
||||
document.getElementById("gateway_response").value =JSON.stringify( details );
|
||||
document.getElementById("server_response").submit();
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
onError: function(err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
}).render('#paypal-button-container');
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
@endpush
|
Loading…
x
Reference in New Issue
Block a user