mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
Support payments and storing cards via WePay.
This commit is contained in:
parent
ba000546c4
commit
ce04c994dd
@ -449,7 +449,7 @@ class AccountGatewayController extends BaseController
|
||||
'tokenType' => $wepayUser->token_type,
|
||||
'tokenExpires' => $accessTokenExpires,
|
||||
'accountId' => $wepayAccount->account_id,
|
||||
'testMode' => WEPAY_ENVIRONMENT == WEPAY_STAGING,
|
||||
'testMode' => WEPAY_ENVIRONMENT == WEPAY_STAGE,
|
||||
));
|
||||
$account->account_gateways()->save($accountGateway);
|
||||
|
||||
|
@ -152,6 +152,8 @@ class PaymentController extends BaseController
|
||||
|
||||
$data = array();
|
||||
|
||||
Session::put($invitation->id.'payment_ref', $invoice->id.'_'.uniqid());
|
||||
|
||||
if ($paymentType != PAYMENT_TYPE_BRAINTREE_PAYPAL) {
|
||||
if ($paymentType == PAYMENT_TYPE_TOKEN) {
|
||||
$useToken = true;
|
||||
@ -198,6 +200,10 @@ class PaymentController extends BaseController
|
||||
$data['braintreeClientToken'] = $this->paymentService->getBraintreeClientToken($account);
|
||||
}
|
||||
|
||||
if(!empty($data['braintreeClientToken']) || $accountGateway->getPublishableStripeKey()|| $accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
$data['tokenize'] = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($deviceData = Input::get('details')) {
|
||||
Session::put($invitation->id . 'device_data', $deviceData);
|
||||
@ -405,7 +411,7 @@ class PaymentController extends BaseController
|
||||
'last_name' => 'required',
|
||||
];
|
||||
|
||||
if ( ! Input::get('stripeToken') && ! Input::get('payment_method_nonce') && !(Input::get('plaidPublicToken') && Input::get('plaidAccountId'))) {
|
||||
if ( ! Input::get('sourceToken') && !(Input::get('plaidPublicToken') && Input::get('plaidAccountId'))) {
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
[
|
||||
@ -459,8 +465,6 @@ class PaymentController extends BaseController
|
||||
$paymentType = Session::get($invitation->id . 'payment_type');
|
||||
$accountGateway = $account->getGatewayByType($paymentType);
|
||||
$paymentMethod = null;
|
||||
|
||||
|
||||
|
||||
if ($useToken) {
|
||||
if(!$sourceId) {
|
||||
@ -492,21 +496,46 @@ class PaymentController extends BaseController
|
||||
$details = $this->paymentService->getPaymentDetails($invitation, $accountGateway, $data);
|
||||
|
||||
// check if we're creating/using a billing token
|
||||
$tokenBillingSupported = false;
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
$tokenBillingSupported = true;
|
||||
$customerReferenceParam = 'cardReference';
|
||||
|
||||
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH && !Input::get('authorize_ach')) {
|
||||
Session::flash('error', trans('texts.ach_authorization_required'));
|
||||
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$tokenBillingSupported = true;
|
||||
$customerReferenceParam = 'paymentMethodToken';
|
||||
|
||||
$deviceData = Input::get('device_data');
|
||||
if (!$deviceData) {
|
||||
$deviceData = Session::get($invitation->id . 'device_data');
|
||||
}
|
||||
|
||||
if($deviceData) {
|
||||
$details['device_data'] = $deviceData;
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
$tokenBillingSupported = true;
|
||||
$customerReferenceParam = false;
|
||||
}
|
||||
|
||||
if ($tokenBillingSupported) {
|
||||
if ($useToken) {
|
||||
$details['customerReference'] = $customerReference;
|
||||
unset($details['token']);
|
||||
$details['cardReference'] = $sourceReference;
|
||||
if ($customerReferenceParam) {
|
||||
$details[$customerReferenceParam] = $customerReference;
|
||||
}
|
||||
$details['token'] = $sourceReference;
|
||||
unset($details['card']);
|
||||
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing') || $paymentType == PAYMENT_TYPE_STRIPE_ACH) {
|
||||
$token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference/* return parameter */, $paymentMethod/* return parameter */);
|
||||
if ($token) {
|
||||
$details['token'] = $token;
|
||||
$details['customerReference'] = $customerReference;
|
||||
if ($customerReferenceParam) {
|
||||
$details[$customerReferenceParam] = $customerReference;
|
||||
}
|
||||
|
||||
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH && empty(Input::get('plaidPublicToken')) ) {
|
||||
// The user needs to complete verification
|
||||
@ -518,36 +547,6 @@ class PaymentController extends BaseController
|
||||
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
||||
}
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$deviceData = Input::get('device_data');
|
||||
if (!$deviceData) {
|
||||
$deviceData = Session::get($invitation->id . 'device_data');
|
||||
}
|
||||
|
||||
if ($token = Input::get('payment_method_nonce')) {
|
||||
$details['token'] = $token;
|
||||
unset($details['card']);
|
||||
}
|
||||
|
||||
if ($useToken) {
|
||||
$details['customerId'] = $customerReference;
|
||||
$details['paymentMethodToken'] = $sourceReference;
|
||||
unset($details['token']);
|
||||
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
|
||||
$token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference/* return parameter */, $paymentMethod/* return parameter */);
|
||||
if ($token) {
|
||||
$details['paymentMethodToken'] = $token;
|
||||
$details['customerId'] = $customerReference;
|
||||
unset($details['token']);
|
||||
} else {
|
||||
$this->error('Token-No-Ref', $this->paymentService->lastError, $accountGateway);
|
||||
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
|
||||
}
|
||||
}
|
||||
|
||||
if($deviceData) {
|
||||
$details['deviceData'] = $deviceData;
|
||||
}
|
||||
}
|
||||
|
||||
$response = $gateway->purchase($details)->send();
|
||||
|
@ -859,7 +859,6 @@ class PublicClientController extends BaseController
|
||||
];
|
||||
|
||||
if ($paymentType == PAYMENT_TYPE_STRIPE_ACH) {
|
||||
|
||||
$data['currencies'] = Cache::get('currencies');
|
||||
}
|
||||
|
||||
@ -867,6 +866,10 @@ class PublicClientController extends BaseController
|
||||
$data['braintreeClientToken'] = $this->paymentService->getBraintreeClientToken($account);
|
||||
}
|
||||
|
||||
if(!empty($data['braintreeClientToken']) || $accountGateway->getPublishableStripeKey()|| $accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
$data['tokenize'] = true;
|
||||
}
|
||||
|
||||
return View::make('payments.add_paymentmethod', $data);
|
||||
}
|
||||
|
||||
@ -882,7 +885,7 @@ class PublicClientController extends BaseController
|
||||
$account = $client->account;
|
||||
|
||||
$accountGateway = $account->getGatewayByType($paymentType);
|
||||
$sourceToken = $accountGateway->gateway_id == GATEWAY_STRIPE ? Input::get('stripeToken'):Input::get('payment_method_nonce');
|
||||
$sourceToken = Input::get('sourceToken');
|
||||
|
||||
if (!PaymentController::processPaymentClientDetails($client, $accountGateway, $paymentType)) {
|
||||
return Redirect::to('client/paymentmethods/add/' . $typeLink)->withInput(Request::except('cvv'));
|
||||
|
@ -562,6 +562,10 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('GATEWAY_WEPAY', 60);
|
||||
define('GATEWAY_BRAINTREE', 61);
|
||||
|
||||
// The customer exists, but only as a local concept
|
||||
// The remote gateway doesn't understand the concept of customers
|
||||
define('CUSTOMER_REFERENCE_LOCAL', 'local');
|
||||
|
||||
define('EVENT_CREATE_CLIENT', 1);
|
||||
define('EVENT_CREATE_INVOICE', 2);
|
||||
define('EVENT_CREATE_QUOTE', 3);
|
||||
@ -749,7 +753,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
|
||||
// WePay
|
||||
define('WEPAY_PRODUCTION', 'production');
|
||||
define('WEPAY_STAGING', 'staging');
|
||||
define('WEPAY_STAGE', 'stage');
|
||||
define('WEPAY_CLIENT_ID', env('WEPAY_CLIENT_ID'));
|
||||
define('WEPAY_CLIENT_SECRET', env('WEPAY_CLIENT_SECRET'));
|
||||
define('WEPAY_ENVIRONMENT', env('WEPAY_ENVIRONMENT', WEPAY_PRODUCTION));
|
||||
|
@ -995,7 +995,7 @@ class Utils
|
||||
public static function setupWePay($accountGateway = null)
|
||||
{
|
||||
if (WePay::getEnvironment() == 'none') {
|
||||
if (WEPAY_ENVIRONMENT == WEPAY_STAGING) {
|
||||
if (WEPAY_ENVIRONMENT == WEPAY_STAGE) {
|
||||
WePay::useStaging(WEPAY_CLIENT_ID, WEPAY_CLIENT_SECRET);
|
||||
} else {
|
||||
WePay::useProduction(WEPAY_CLIENT_ID, WEPAY_CLIENT_SECRET);
|
||||
|
@ -1245,6 +1245,8 @@ class Account extends Eloquent
|
||||
return GATEWAY_STRIPE;
|
||||
} elseif ($this->isGatewayConfigured(GATEWAY_BRAINTREE)) {
|
||||
return GATEWAY_BRAINTREE;
|
||||
} elseif ($this->isGatewayConfigured(GATEWAY_WEPAY)) {
|
||||
return GATEWAY_WEPAY;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class AccountGatewayService extends BaseService
|
||||
return link_to("gateways/{$model->public_id}/edit", $model->name)->toHtml();
|
||||
} else {
|
||||
$accountGateway = AccountGateway::find($model->id);
|
||||
$endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGING ? 'https://stage.wepay.com/' : 'https://www.wepay.com/';
|
||||
$endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGE ? 'https://stage.wepay.com/' : 'https://www.wepay.com/';
|
||||
$wepayAccountId = $accountGateway->getConfig()->accountId;
|
||||
$linkText = $model->name;
|
||||
$url = $endpoint.'account/'.$wepayAccountId;
|
||||
@ -116,7 +116,7 @@ class AccountGatewayService extends BaseService
|
||||
uctrans('texts.manage_wepay_account'),
|
||||
function ($model) {
|
||||
$accountGateway = AccountGateway::find($model->id);
|
||||
$endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGING ? 'https://stage.wepay.com/' : 'https://www.wepay.com/';
|
||||
$endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGE ? 'https://stage.wepay.com/' : 'https://www.wepay.com/';
|
||||
return array(
|
||||
'url' => $endpoint.'account/'.$accountGateway->getConfig()->accountId,
|
||||
'attributes' => 'target="_blank"'
|
||||
|
@ -9,6 +9,7 @@ use Cache;
|
||||
use Omnipay;
|
||||
use Session;
|
||||
use CreditCard;
|
||||
use WePay;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Models\Account;
|
||||
@ -30,7 +31,8 @@ class PaymentService extends BaseService
|
||||
|
||||
protected static $refundableGateways = array(
|
||||
GATEWAY_STRIPE,
|
||||
GATEWAY_BRAINTREE
|
||||
GATEWAY_BRAINTREE,
|
||||
GATEWAY_WEPAY,
|
||||
);
|
||||
|
||||
public function __construct(PaymentRepository $paymentRepo, AccountRepository $accountRepo, DatatableService $datatableService)
|
||||
@ -95,9 +97,9 @@ class PaymentService extends BaseService
|
||||
$data['ButtonSource'] = 'InvoiceNinja_SP';
|
||||
};
|
||||
|
||||
if ($input && $accountGateway->isGateway(GATEWAY_STRIPE)) {
|
||||
if (!empty($input['stripeToken'])) {
|
||||
$data['token'] = $input['stripeToken'];
|
||||
if ($input) {
|
||||
if (!empty($input['sourceToken'])) {
|
||||
$data['token'] = $input['sourceToken'];
|
||||
unset($data['card']);
|
||||
} elseif (!empty($input['plaidPublicToken'])) {
|
||||
$data['plaidPublicToken'] = $input['plaidPublicToken'];
|
||||
@ -106,6 +108,10 @@ class PaymentService extends BaseService
|
||||
}
|
||||
}
|
||||
|
||||
if ($accountGateway->isGateway(GATEWAY_WEPAY) && $transactionId = Session::get($invitation->id.'payment_ref')) {
|
||||
$data['transaction_id'] = $transactionId;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@ -266,6 +272,17 @@ class PaymentService extends BaseService
|
||||
if (!$response->isSuccessful()) {
|
||||
return $response->getMessage();
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
try {
|
||||
$wepay = Utils::setupWePay($accountGateway);
|
||||
$wepay->request('/credit_card/delete', [
|
||||
'client_id' => WEPAY_CLIENT_ID,
|
||||
'client_secret' => WEPAY_CLIENT_SECRET,
|
||||
'credit_card_id' => $paymentMethod->source_reference,
|
||||
]);
|
||||
} catch (\WePayException $ex){
|
||||
return $ex->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$paymentMethod->delete();
|
||||
@ -291,16 +308,16 @@ class PaymentService extends BaseService
|
||||
{
|
||||
$customerReference = $client->getGatewayToken($accountGateway, $accountGatewayToken/* return paramenter */);
|
||||
|
||||
if ($customerReference) {
|
||||
if ($customerReference && $customerReference != CUSTOMER_REFERENCE_LOCAL) {
|
||||
$details['customerReference'] = $customerReference;
|
||||
|
||||
if ($accountGateway->gateway->id == GATEWAY_STRIPE) {
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
$customerResponse = $gateway->fetchCustomer(array('customerReference' => $customerReference))->send();
|
||||
|
||||
if (!$customerResponse->isSuccessful()) {
|
||||
$customerReference = null; // The customer might not exist anymore
|
||||
}
|
||||
} elseif ($accountGateway->gateway->id == GATEWAY_BRAINTREE) {
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$customer = $gateway->findCustomer($customerReference)->send()->getData();
|
||||
|
||||
if (!($customer instanceof \Braintree\Customer)) {
|
||||
@ -309,7 +326,7 @@ class PaymentService extends BaseService
|
||||
}
|
||||
}
|
||||
|
||||
if ($accountGateway->gateway->id == GATEWAY_STRIPE) {
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
if (!empty($details['plaidPublicToken'])) {
|
||||
$plaidResult = $this->getPlaidToken($accountGateway, $details['plaidPublicToken'], $details['plaidAccountId']);
|
||||
|
||||
@ -355,7 +372,7 @@ class PaymentService extends BaseService
|
||||
return;
|
||||
}
|
||||
}
|
||||
} elseif ($accountGateway->gateway->id == GATEWAY_BRAINTREE) {
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
if (!$customerReference) {
|
||||
$tokenResponse = $gateway->createCustomer(array('customerData' => array()))->send();
|
||||
if ($tokenResponse->isSuccessful()) {
|
||||
@ -377,6 +394,31 @@ class PaymentService extends BaseService
|
||||
return;
|
||||
}
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
$wepay = Utils::setupWePay($accountGateway);
|
||||
|
||||
try {
|
||||
$wepay->request('credit_card/authorize', array(
|
||||
'client_id' => WEPAY_CLIENT_ID,
|
||||
'client_secret' => WEPAY_CLIENT_SECRET,
|
||||
'credit_card_id' => $details['token'],
|
||||
));
|
||||
|
||||
// Get the card details
|
||||
$tokenResponse = $wepay->request('credit_card', array(
|
||||
'client_id' => WEPAY_CLIENT_ID,
|
||||
'client_secret' => WEPAY_CLIENT_SECRET,
|
||||
'credit_card_id' => $details['token'],
|
||||
));
|
||||
|
||||
$customerReference = CUSTOMER_REFERENCE_LOCAL;
|
||||
$sourceReference = $details['token'];
|
||||
} catch (\WePayException $ex) {
|
||||
$this->lastError = $ex->getMessage();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($customerReference) {
|
||||
@ -394,7 +436,7 @@ class PaymentService extends BaseService
|
||||
$accountGatewayToken->token = $customerReference;
|
||||
$accountGatewayToken->save();
|
||||
|
||||
$paymentMethod = $this->createPaymentMethodFromGatewayResponse($tokenResponse, $accountGateway, $accountGatewayToken, $contactId);
|
||||
$paymentMethod = $this->convertPaymentMethodFromGatewayResponse($tokenResponse, $accountGateway, $accountGatewayToken, $contactId);
|
||||
|
||||
} else {
|
||||
$this->lastError = $tokenResponse->getMessage();
|
||||
@ -456,8 +498,24 @@ class PaymentService extends BaseService
|
||||
|
||||
return $paymentMethod;
|
||||
}
|
||||
|
||||
public function convertPaymentMethodFromWePay($source, $accountGatewayToken = null, $paymentMethod = null) {
|
||||
// Creating a new one or updating an existing one
|
||||
if (!$paymentMethod) {
|
||||
$paymentMethod = $accountGatewayToken ? PaymentMethod::createNew($accountGatewayToken) : new PaymentMethod();
|
||||
}
|
||||
|
||||
$paymentMethod->payment_type_id = $this->parseCardType($source->credit_card_name);
|
||||
$paymentMethod->last4 = $source->last_four;
|
||||
$paymentMethod->expiration = $source->expiration_year . '-' . $source->expiration_month . '-00';
|
||||
$paymentMethod->setRelation('payment_type', Cache::get('paymentTypes')->find($paymentMethod->payment_type_id));
|
||||
|
||||
$paymentMethod->source_reference = $source->credit_card_id;
|
||||
|
||||
return $paymentMethod;
|
||||
}
|
||||
|
||||
public function createPaymentMethodFromGatewayResponse($gatewayResponse, $accountGateway, $accountGatewayToken = null, $contactId = null) {
|
||||
public function convertPaymentMethodFromGatewayResponse($gatewayResponse, $accountGateway, $accountGatewayToken = null, $contactId = null, $existingPaymentMethod = null) {
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
$data = $gatewayResponse->getData();
|
||||
if (!empty($data['object']) && ($data['object'] == 'card' || $data['object'] == 'bank_account')) {
|
||||
@ -470,7 +528,7 @@ class PaymentService extends BaseService
|
||||
}
|
||||
|
||||
if ($source) {
|
||||
$paymentMethod = $this->convertPaymentMethodFromStripe($source, $accountGatewayToken);
|
||||
$paymentMethod = $this->convertPaymentMethodFromStripe($source, $accountGatewayToken, $existingPaymentMethod);
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$data = $gatewayResponse->getData();
|
||||
@ -478,7 +536,12 @@ class PaymentService extends BaseService
|
||||
if (!empty($data->transaction)) {
|
||||
$transaction = $data->transaction;
|
||||
|
||||
$paymentMethod = $accountGatewayToken ? PaymentMethod::createNew($accountGatewayToken) : new PaymentMethod();
|
||||
if ($existingPaymentMethod) {
|
||||
$paymentMethod = $existingPaymentMethod;
|
||||
} else {
|
||||
$paymentMethod = $accountGatewayToken ? PaymentMethod::createNew($accountGatewayToken) : new PaymentMethod();
|
||||
}
|
||||
|
||||
if ($transaction->paymentInstrumentType == 'credit_card') {
|
||||
$card = $transaction->creditCardDetails;
|
||||
$paymentMethod->last4 = $card->last4;
|
||||
@ -490,9 +553,20 @@ class PaymentService extends BaseService
|
||||
}
|
||||
$paymentMethod->setRelation('payment_type', Cache::get('paymentTypes')->find($paymentMethod->payment_type_id));
|
||||
} elseif (!empty($data->paymentMethod)) {
|
||||
$paymentMethod = $this->convertPaymentMethodFromBraintree($data->paymentMethod, $accountGatewayToken);
|
||||
$paymentMethod = $this->convertPaymentMethodFromBraintree($data->paymentMethod, $accountGatewayToken, $existingPaymentMethod);
|
||||
}
|
||||
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
if ($gatewayResponse instanceof \Omnipay\WePay\Message\CustomCheckoutResponse) {
|
||||
$wepay = \Utils::setupWePay($accountGateway);
|
||||
$gatewayResponse = $wepay->request('credit_card', array(
|
||||
'client_id' => WEPAY_CLIENT_ID,
|
||||
'client_secret' => WEPAY_CLIENT_SECRET,
|
||||
'credit_card_id' => $gatewayResponse->getData()['payment_method']['credit_card']['id'],
|
||||
));
|
||||
|
||||
}
|
||||
$paymentMethod = $this->convertPaymentMethodFromWePay($gatewayResponse, $accountGatewayToken, $existingPaymentMethod);
|
||||
}
|
||||
|
||||
if (!empty($paymentMethod) && $accountGatewayToken && $contactId) {
|
||||
@ -566,43 +640,49 @@ class PaymentService extends BaseService
|
||||
$payment->payment_type_id = $this->detectCardType($card->getNumber());
|
||||
}
|
||||
|
||||
$savePaymentMethod = !empty($paymentMethod);
|
||||
|
||||
// This will convert various gateway's formats to a known format
|
||||
$paymentMethod = $this->convertPaymentMethodFromGatewayResponse($purchaseResponse, $accountGateway, null, null, $paymentMethod);
|
||||
|
||||
// If this is a stored payment method, we'll update it with the latest info
|
||||
if ($savePaymentMethod) {
|
||||
$paymentMethod->save();
|
||||
}
|
||||
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
$data = $purchaseResponse->getData();
|
||||
$source = !empty($data['source'])?$data['source']:$data['card'];
|
||||
|
||||
$payment->payment_status_id = $data['status'] == 'succeeded' ? PAYMENT_STATUS_COMPLETED : PAYMENT_STATUS_PENDING;
|
||||
|
||||
if ($source) {
|
||||
$payment->last4 = $source['last4'];
|
||||
|
||||
if ($source['object'] == 'bank_account') {
|
||||
$payment->routing_number = $source['routing_number'];
|
||||
$payment->payment_type_id = PAYMENT_TYPE_ACH;
|
||||
}
|
||||
else{
|
||||
$payment->expiration = $source['exp_year'] . '-' . $source['exp_month'] . '-00';
|
||||
$payment->payment_type_id = $this->parseCardType($source['brand']);
|
||||
}
|
||||
}
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$transaction = $purchaseResponse->getData()->transaction;
|
||||
if ($transaction->paymentInstrumentType == 'credit_card') {
|
||||
$card = $transaction->creditCardDetails;
|
||||
$payment->last4 = $card->last4;
|
||||
$payment->expiration = $card->expirationYear . '-' . $card->expirationMonth . '-00';
|
||||
$payment->payment_type_id = $this->parseCardType($card->cardType);
|
||||
} elseif ($transaction->paymentInstrumentType == 'paypal_account') {
|
||||
$payment->payment_type_id = PAYMENT_TYPE_ID_PAYPAL;
|
||||
$payment->email = $transaction->paypalDetails->payerEmail;
|
||||
}
|
||||
}
|
||||
|
||||
if ($payerId) {
|
||||
$payment->payer_id = $payerId;
|
||||
}
|
||||
|
||||
if ($paymentMethod) {
|
||||
$payment->payment_method_id = $paymentMethod->id;
|
||||
if ($paymentMethod->last4) {
|
||||
$payment->last4 = $paymentMethod->last4;
|
||||
}
|
||||
|
||||
if ($paymentMethod->expiration) {
|
||||
$payment->expiration = $paymentMethod->expiration;
|
||||
}
|
||||
|
||||
if ($paymentMethod->routing_number) {
|
||||
$payment->routing_number = $paymentMethod->routing_number;
|
||||
}
|
||||
|
||||
if ($paymentMethod->payment_type_id) {
|
||||
$payment->payment_type_id = $paymentMethod->payment_type_id;
|
||||
}
|
||||
|
||||
if ($paymentMethod->email) {
|
||||
$payment->email = $paymentMethod->email;
|
||||
}
|
||||
|
||||
if ($payerId) {
|
||||
$payment->payer_id = $payerId;
|
||||
}
|
||||
|
||||
if ($savePaymentMethod) {
|
||||
$payment->payment_method_id = $paymentMethod->id;
|
||||
}
|
||||
}
|
||||
|
||||
$payment->save();
|
||||
@ -665,20 +745,29 @@ class PaymentService extends BaseService
|
||||
|
||||
private function parseCardType($cardName) {
|
||||
$cardTypes = array(
|
||||
'Visa' => PAYMENT_TYPE_VISA,
|
||||
'American Express' => PAYMENT_TYPE_AMERICAN_EXPRESS,
|
||||
'MasterCard' => PAYMENT_TYPE_MASTERCARD,
|
||||
'Discover' => PAYMENT_TYPE_DISCOVER,
|
||||
'JCB' => PAYMENT_TYPE_JCB,
|
||||
'Diners Club' => PAYMENT_TYPE_DINERS,
|
||||
'Carte Blanche' => PAYMENT_TYPE_CARTE_BLANCHE,
|
||||
'China UnionPay' => PAYMENT_TYPE_UNIONPAY,
|
||||
'Laser' => PAYMENT_TYPE_LASER,
|
||||
'Maestro' => PAYMENT_TYPE_MAESTRO,
|
||||
'Solo' => PAYMENT_TYPE_SOLO,
|
||||
'Switch' => PAYMENT_TYPE_SWITCH
|
||||
'visa' => PAYMENT_TYPE_VISA,
|
||||
'americanexpress' => PAYMENT_TYPE_AMERICAN_EXPRESS,
|
||||
'amex' => PAYMENT_TYPE_AMERICAN_EXPRESS,
|
||||
'mastercard' => PAYMENT_TYPE_MASTERCARD,
|
||||
'discover' => PAYMENT_TYPE_DISCOVER,
|
||||
'jcb' => PAYMENT_TYPE_JCB,
|
||||
'dinersclub' => PAYMENT_TYPE_DINERS,
|
||||
'carteblanche' => PAYMENT_TYPE_CARTE_BLANCHE,
|
||||
'chinaunionpay' => PAYMENT_TYPE_UNIONPAY,
|
||||
'unionpay' => PAYMENT_TYPE_UNIONPAY,
|
||||
'laser' => PAYMENT_TYPE_LASER,
|
||||
'maestro' => PAYMENT_TYPE_MAESTRO,
|
||||
'solo' => PAYMENT_TYPE_SOLO,
|
||||
'switch' => PAYMENT_TYPE_SWITCH
|
||||
);
|
||||
|
||||
$cardName = strtolower(str_replace(array(' ', '-', '_'), '', $cardName));
|
||||
|
||||
if (empty($cardTypes[$cardName]) && 1 == preg_match('/^('.implode('|', array_keys($cardTypes)).')/', $cardName, $matches)) {
|
||||
// Some gateways return extra stuff after the card name
|
||||
$cardName = $matches[1];
|
||||
}
|
||||
|
||||
if (!empty($cardTypes[$cardName])) {
|
||||
return $cardTypes[$cardName];
|
||||
} else {
|
||||
@ -736,10 +825,9 @@ class PaymentService extends BaseService
|
||||
$details = $this->getPaymentDetails($invitation, $accountGateway);
|
||||
$details['customerReference'] = $token;
|
||||
|
||||
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||
$details['cardReference'] = $defaultPaymentMethod->source_reference;
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
|
||||
$details['paymentMethodToken'] = $defaultPaymentMethod->source_reference;
|
||||
$details['token'] = $defaultPaymentMethod->source_reference;
|
||||
if ($accountGateway->gateway_id == GATEWAY_WEPAY) {
|
||||
$details['transaction_id'] = 'autobill_'.$invoice->id;
|
||||
}
|
||||
|
||||
// submit purchase/get response
|
||||
|
@ -3,221 +3,11 @@
|
||||
@section('head')
|
||||
@parent
|
||||
@if (!empty($braintreeClientToken))
|
||||
<script type="text/javascript" src="https://js.braintreegateway.com/js/braintree-2.23.0.min.js"></script>
|
||||
<script type="text/javascript" >
|
||||
$(function() {
|
||||
braintree.setup("{{ $braintreeClientToken }}", "custom", {
|
||||
id: "payment-form",
|
||||
hostedFields: {
|
||||
number: {
|
||||
selector: "#card_number",
|
||||
placeholder: "{{ trans('texts.card_number') }}"
|
||||
},
|
||||
cvv: {
|
||||
selector: "#cvv",
|
||||
placeholder: "{{ trans('texts.cvv') }}"
|
||||
},
|
||||
expirationMonth: {
|
||||
selector: "#expiration_month",
|
||||
placeholder: "{{ trans('texts.expiration_month') }}"
|
||||
},
|
||||
expirationYear: {
|
||||
selector: "#expiration_year",
|
||||
placeholder: "{{ trans('texts.expiration_year') }}"
|
||||
},
|
||||
styles: {
|
||||
'input': {
|
||||
'font-family': {!! json_encode(Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_stack']) !!},
|
||||
'font-weight': "{{ Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_weight'] }}",
|
||||
'font-size': '16px'
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: function(e) {
|
||||
var $form = $('.payment-form');
|
||||
$form.find('button').prop('disabled', false);
|
||||
// Show the errors on the form
|
||||
if (e.details && e.details.invalidFieldKeys.length) {
|
||||
var invalidField = e.details.invalidFieldKeys[0];
|
||||
|
||||
if (invalidField == 'number') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
|
||||
}
|
||||
else if (invalidField == 'expirationDate' || invalidField == 'expirationYear' || invalidField == 'expirationMonth') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
|
||||
}
|
||||
else if (invalidField == 'cvv') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#js-error-message').html(e.message).fadeIn();
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.payment-form').submit(function(event) {
|
||||
var $form = $(this);
|
||||
|
||||
// Disable the submit button to prevent repeated clicks
|
||||
$form.find('button').prop('disabled', true);
|
||||
$('#js-error-message').hide();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@include('payments.tokenization_braintree')
|
||||
@elseif (isset($accountGateway) && $accountGateway->getPublishableStripeKey())
|
||||
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
|
||||
<script type="text/javascript">
|
||||
Stripe.setPublishableKey('{{ $accountGateway->getPublishableStripeKey() }}');
|
||||
$(function() {
|
||||
$('.payment-form').submit(function(event) {
|
||||
if($('[name=plaidAccountId]').length)return;
|
||||
|
||||
var $form = $(this);
|
||||
|
||||
var data = {
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
account_holder_name: $('#account_holder_name').val(),
|
||||
account_holder_type: $('[name=account_holder_type]:checked').val(),
|
||||
currency: $("#currency").val(),
|
||||
country: $("#country").val(),
|
||||
routing_number: $('#routing_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''),
|
||||
account_number: $('#account_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
|
||||
@else
|
||||
name: $('#first_name').val() + ' ' + $('#last_name').val(),
|
||||
address_line1: $('#address1').val(),
|
||||
address_line2: $('#address2').val(),
|
||||
address_city: $('#city').val(),
|
||||
address_state: $('#state').val(),
|
||||
address_zip: $('#postal_code').val(),
|
||||
address_country: $("#country_id option:selected").text(),
|
||||
number: $('#card_number').val(),
|
||||
cvc: $('#cvv').val(),
|
||||
exp_month: $('#expiration_month').val(),
|
||||
exp_year: $('#expiration_year').val()
|
||||
@endif
|
||||
};
|
||||
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
// Validate the account details
|
||||
if (!data.account_holder_type) {
|
||||
$('#js-error-message').html('{{ trans('texts.missing_account_holder_type') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.account_holder_name) {
|
||||
$('#js-error-message').html('{{ trans('texts.missing_account_holder_name') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.routing_number || !Stripe.bankAccount.validateRoutingNumber(data.routing_number, data.country)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_routing_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (data.account_number != $('#confirm_account_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')) {
|
||||
$('#js-error-message').html('{{ trans('texts.account_number_mismatch') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.account_number || !Stripe.bankAccount.validateAccountNumber(data.account_number, data.country)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_account_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
@else
|
||||
// Validate the card details
|
||||
if (!Stripe.card.validateCardNumber(data.number)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!Stripe.card.validateExpiry(data.exp_month, data.exp_year)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!Stripe.card.validateCVC(data.cvc)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
@endif
|
||||
|
||||
// Disable the submit button to prevent repeated clicks
|
||||
$form.find('button').prop('disabled', true);
|
||||
$('#js-error-message').hide();
|
||||
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
Stripe.bankAccount.createToken(data, stripeResponseHandler);
|
||||
@else
|
||||
Stripe.card.createToken(data, stripeResponseHandler);
|
||||
@endif
|
||||
|
||||
// Prevent the form from submitting with the default action
|
||||
return false;
|
||||
});
|
||||
|
||||
@if($accountGateway->getPlaidEnabled())
|
||||
var plaidHandler = Plaid.create({
|
||||
selectAccount: true,
|
||||
env: '{{ $accountGateway->getPlaidEnvironment() }}',
|
||||
clientName: {!! json_encode($account->getDisplayName()) !!},
|
||||
key: '{{ $accountGateway->getPlaidPublicKey() }}',
|
||||
product: 'auth',
|
||||
onSuccess: plaidSuccessHandler,
|
||||
onExit : function(){$('#secured_by_plaid').hide()}
|
||||
});
|
||||
|
||||
$('#plaid_link_button').click(function(){plaidHandler.open();$('#secured_by_plaid').fadeIn()});
|
||||
$('#plaid_unlink').click(function(e){
|
||||
e.preventDefault();
|
||||
$('#manual_container').fadeIn();
|
||||
$('#plaid_linked').hide();
|
||||
$('#plaid_link_button').show();
|
||||
$('#pay_now_button').hide();
|
||||
$('#add_account_button').show();
|
||||
$('[name=plaidPublicToken]').remove();
|
||||
$('[name=plaidAccountId]').remove();
|
||||
$('[name=account_holder_type],#account_holder_name').attr('required','required');
|
||||
})
|
||||
@endif
|
||||
});
|
||||
|
||||
function stripeResponseHandler(status, response) {
|
||||
var $form = $('.payment-form');
|
||||
|
||||
if (response.error) {
|
||||
// Show the errors on the form
|
||||
var error = response.error.message;
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
if(response.error.param == 'bank_account[country]') {
|
||||
error = "{{trans('texts.country_not_supported')}}";
|
||||
}
|
||||
@endif
|
||||
$form.find('button').prop('disabled', false);
|
||||
$('#js-error-message').html(error).fadeIn();
|
||||
} else {
|
||||
// response contains id and card, which contains additional card details
|
||||
var token = response.id;
|
||||
// Insert the token into the form so it gets submitted to the server
|
||||
$form.append($('<input type="hidden" name="stripeToken"/>').val(token));
|
||||
// and submit
|
||||
$form.get(0).submit();
|
||||
}
|
||||
};
|
||||
|
||||
function plaidSuccessHandler(public_token, metadata) {
|
||||
$('#secured_by_plaid').hide()
|
||||
var $form = $('.payment-form');
|
||||
|
||||
$form.append($('<input type="hidden" name="plaidPublicToken"/>').val(public_token));
|
||||
$form.append($('<input type="hidden" name="plaidAccountId"/>').val(metadata.account_id));
|
||||
$('#plaid_linked_status').text('{{ trans('texts.plaid_linked_status') }}'.replace(':bank', metadata.institution.name));
|
||||
$('#manual_container').fadeOut();
|
||||
$('#plaid_linked').show();
|
||||
$('#plaid_link_button').hide();
|
||||
$('[name=account_holder_type],#account_holder_name').removeAttr('required');
|
||||
|
||||
|
||||
var payNowBtn = $('#pay_now_button');
|
||||
if(payNowBtn.length) {
|
||||
payNowBtn.show();
|
||||
$('#add_account_button').hide();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@include('payments.tokenization_stripe')
|
||||
@elseif (isset($accountGateway) && $accountGateway->gateway_id == GATEWAY_WEPAY)
|
||||
@include('payments.tokenization_wepay')
|
||||
@else
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
@ -232,7 +22,6 @@
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
@ -283,7 +72,6 @@
|
||||
{{ Former::populateField('email', $contact->email) }}
|
||||
@if (!$client->country_id && $client->account->country_id)
|
||||
{{ Former::populateField('country_id', $client->account->country_id) }}
|
||||
{{ Former::populateField('country', $client->account->country->iso_3166_2) }}
|
||||
@endif
|
||||
@if (!$client->currency_id && $client->account->currency_id)
|
||||
{{ Former::populateField('currency_id', $client->account->currency_id) }}
|
||||
@ -442,9 +230,9 @@
|
||||
))->inline()->label(trans('texts.account_holder_type')); !!}
|
||||
{!! Former::text('account_holder_name')
|
||||
->label(trans('texts.account_holder_name')) !!}
|
||||
{!! Former::select('country')
|
||||
{!! Former::select('country_id')
|
||||
->label(trans('texts.country_id'))
|
||||
->fromQuery($countries, 'name', 'iso_3166_2')
|
||||
->fromQuery($countries, 'name', 'id')
|
||||
->addGroupClass('country-select') !!}
|
||||
{!! Former::select('currency')
|
||||
->label(trans('texts.currency_id'))
|
||||
@ -485,7 +273,7 @@
|
||||
<h3>{{ trans('texts.paypal') }}</h3>
|
||||
<div>{{$paypalDetails->firstName}} {{$paypalDetails->lastName}}</div>
|
||||
<div>{{$paypalDetails->email}}</div>
|
||||
<input type="hidden" name="payment_method_nonce" value="{{$sourceId}}">
|
||||
<input type="hidden" name="sourceToken" value="{{$sourceId}}">
|
||||
<input type="hidden" name="first_name" value="{{$paypalDetails->firstName}}">
|
||||
<input type="hidden" name="last_name" value="{{$paypalDetails->lastName}}">
|
||||
<input type="hidden" name="email" value="{{$paypalDetails->email}}">
|
||||
@ -515,7 +303,7 @@
|
||||
@if (!empty($braintreeClientToken))
|
||||
<div id="card_number" class="braintree-hosted form-control"></div>
|
||||
@else
|
||||
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'card_number')
|
||||
{!! Former::text(!empty($tokenize) ? '' : 'card_number')
|
||||
->id('card_number')
|
||||
->placeholder(trans('texts.card_number'))
|
||||
->autocomplete('cc-number')
|
||||
@ -526,7 +314,7 @@
|
||||
@if (!empty($braintreeClientToken))
|
||||
<div id="cvv" class="braintree-hosted form-control"></div>
|
||||
@else
|
||||
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv')
|
||||
{!! Former::text(!empty($tokenize) ? '' : 'cvv')
|
||||
->id('cvv')
|
||||
->placeholder(trans('texts.cvv'))
|
||||
->autocomplete('off')
|
||||
@ -539,7 +327,7 @@
|
||||
@if (!empty($braintreeClientToken))
|
||||
<div id="expiration_month" class="braintree-hosted form-control"></div>
|
||||
@else
|
||||
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_month')
|
||||
{!! Former::select(!empty($tokenize) ? '' : 'expiration_month')
|
||||
->id('expiration_month')
|
||||
->autocomplete('cc-exp-month')
|
||||
->placeholder(trans('texts.expiration_month'))
|
||||
@ -562,7 +350,7 @@
|
||||
@if (!empty($braintreeClientToken))
|
||||
<div id="expiration_year" class="braintree-hosted form-control"></div>
|
||||
@else
|
||||
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_year')
|
||||
{!! Former::select(!empty($tokenize) ? '' : 'expiration_year')
|
||||
->id('expiration_year')
|
||||
->autocomplete('cc-exp-year')
|
||||
->placeholder(trans('texts.expiration_year'))
|
||||
|
@ -183,5 +183,6 @@
|
||||
function setDefault(sourceId) {
|
||||
$('#default_id').val(sourceId);
|
||||
$('#defaultSourceForm').submit()
|
||||
return false;
|
||||
}
|
||||
</script>
|
61
resources/views/payments/tokenization_braintree.blade.php
Normal file
61
resources/views/payments/tokenization_braintree.blade.php
Normal file
@ -0,0 +1,61 @@
|
||||
<script type="text/javascript" src="https://js.braintreegateway.com/js/braintree-2.23.0.min.js"></script>
|
||||
<script type="text/javascript" >
|
||||
$(function() {
|
||||
braintree.setup("{{ $braintreeClientToken }}", "custom", {
|
||||
id: "payment-form",
|
||||
hostedFields: {
|
||||
number: {
|
||||
selector: "#card_number",
|
||||
placeholder: "{{ trans('texts.card_number') }}"
|
||||
},
|
||||
cvv: {
|
||||
selector: "#cvv",
|
||||
placeholder: "{{ trans('texts.cvv') }}"
|
||||
},
|
||||
expirationMonth: {
|
||||
selector: "#expiration_month",
|
||||
placeholder: "{{ trans('texts.expiration_month') }}"
|
||||
},
|
||||
expirationYear: {
|
||||
selector: "#expiration_year",
|
||||
placeholder: "{{ trans('texts.expiration_year') }}"
|
||||
},
|
||||
styles: {
|
||||
'input': {
|
||||
'font-family': {!! json_encode(Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_stack']) !!},
|
||||
'font-weight': "{{ Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_weight'] }}",
|
||||
'font-size': '16px'
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: function(e) {
|
||||
var $form = $('.payment-form');
|
||||
$form.find('button').prop('disabled', false);
|
||||
// Show the errors on the form
|
||||
if (e.details && e.details.invalidFieldKeys.length) {
|
||||
var invalidField = e.details.invalidFieldKeys[0];
|
||||
|
||||
if (invalidField == 'number') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
|
||||
}
|
||||
else if (invalidField == 'expirationDate' || invalidField == 'expirationYear' || invalidField == 'expirationMonth') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
|
||||
}
|
||||
else if (invalidField == 'cvv') {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#js-error-message').html(e.message).fadeIn();
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.payment-form').submit(function(event) {
|
||||
var $form = $(this);
|
||||
|
||||
// Disable the submit button to prevent repeated clicks
|
||||
$form.find('button').prop('disabled', true);
|
||||
$('#js-error-message').hide();
|
||||
});
|
||||
});
|
||||
</script>
|
154
resources/views/payments/tokenization_stripe.blade.php
Normal file
154
resources/views/payments/tokenization_stripe.blade.php
Normal file
@ -0,0 +1,154 @@
|
||||
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
|
||||
<script type="text/javascript">
|
||||
Stripe.setPublishableKey('{{ $accountGateway->getPublishableStripeKey() }}');
|
||||
$(function() {
|
||||
var countries = {!! $countries->pluck('iso_3166_2','id') !!};
|
||||
$('.payment-form').submit(function(event) {
|
||||
if($('[name=plaidAccountId]').length)return;
|
||||
|
||||
var $form = $(this);
|
||||
|
||||
var data = {
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
account_holder_name: $('#account_holder_name').val(),
|
||||
account_holder_type: $('[name=account_holder_type]:checked').val(),
|
||||
currency: $("#currency").val(),
|
||||
country: countries[$("#country_id").val()],
|
||||
routing_number: $('#routing_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''),
|
||||
account_number: $('#account_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
|
||||
@else
|
||||
name: $('#first_name').val() + ' ' + $('#last_name').val(),
|
||||
address_line1: $('#address1').val(),
|
||||
address_line2: $('#address2').val(),
|
||||
address_city: $('#city').val(),
|
||||
address_state: $('#state').val(),
|
||||
address_zip: $('#postal_code').val(),
|
||||
address_country: $("#country_id option:selected").text(),
|
||||
number: $('#card_number').val(),
|
||||
cvc: $('#cvv').val(),
|
||||
exp_month: $('#expiration_month').val(),
|
||||
exp_year: $('#expiration_year').val()
|
||||
@endif
|
||||
};
|
||||
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
// Validate the account details
|
||||
if (!data.account_holder_type) {
|
||||
$('#js-error-message').html('{{ trans('texts.missing_account_holder_type') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.account_holder_name) {
|
||||
$('#js-error-message').html('{{ trans('texts.missing_account_holder_name') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.routing_number || !Stripe.bankAccount.validateRoutingNumber(data.routing_number, data.country)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_routing_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (data.account_number != $('#confirm_account_number').val().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')) {
|
||||
$('#js-error-message').html('{{ trans('texts.account_number_mismatch') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!data.account_number || !Stripe.bankAccount.validateAccountNumber(data.account_number, data.country)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_account_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
@else
|
||||
// Validate the card details
|
||||
if (!Stripe.card.validateCardNumber(data.number)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!Stripe.card.validateExpiry(data.exp_month, data.exp_year)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
if (!Stripe.card.validateCVC(data.cvc)) {
|
||||
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
|
||||
return false;
|
||||
}
|
||||
@endif
|
||||
|
||||
// Disable the submit button to prevent repeated clicks
|
||||
$form.find('button').prop('disabled', true);
|
||||
$('#js-error-message').hide();
|
||||
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
Stripe.bankAccount.createToken(data, stripeResponseHandler);
|
||||
@else
|
||||
Stripe.card.createToken(data, stripeResponseHandler);
|
||||
@endif
|
||||
|
||||
// Prevent the form from submitting with the default action
|
||||
return false;
|
||||
});
|
||||
|
||||
@if($accountGateway->getPlaidEnabled())
|
||||
var plaidHandler = Plaid.create({
|
||||
selectAccount: true,
|
||||
env: '{{ $accountGateway->getPlaidEnvironment() }}',
|
||||
clientName: {!! json_encode($account->getDisplayName()) !!},
|
||||
key: '{{ $accountGateway->getPlaidPublicKey() }}',
|
||||
product: 'auth',
|
||||
onSuccess: plaidSuccessHandler,
|
||||
onExit : function(){$('#secured_by_plaid').hide()}
|
||||
});
|
||||
|
||||
$('#plaid_link_button').click(function(){plaidHandler.open();$('#secured_by_plaid').fadeIn()});
|
||||
$('#plaid_unlink').click(function(e){
|
||||
e.preventDefault();
|
||||
$('#manual_container').fadeIn();
|
||||
$('#plaid_linked').hide();
|
||||
$('#plaid_link_button').show();
|
||||
$('#pay_now_button').hide();
|
||||
$('#add_account_button').show();
|
||||
$('[name=plaidPublicToken]').remove();
|
||||
$('[name=plaidAccountId]').remove();
|
||||
$('[name=account_holder_type],#account_holder_name').attr('required','required');
|
||||
})
|
||||
@endif
|
||||
});
|
||||
|
||||
function stripeResponseHandler(status, response) {
|
||||
var $form = $('.payment-form');
|
||||
|
||||
if (response.error) {
|
||||
// Show the errors on the form
|
||||
var error = response.error.message;
|
||||
@if($paymentType == PAYMENT_TYPE_STRIPE_ACH)
|
||||
if(response.error.param == 'bank_account[country]') {
|
||||
error = "{{trans('texts.country_not_supported')}}";
|
||||
}
|
||||
@endif
|
||||
$form.find('button').prop('disabled', false);
|
||||
$('#js-error-message').html(error).fadeIn();
|
||||
} else {
|
||||
// response contains id and card, which contains additional card details
|
||||
var token = response.id;
|
||||
// Insert the token into the form so it gets submitted to the server
|
||||
$form.append($('<input type="hidden" name="sourceToken"/>').val(token));
|
||||
// and submit
|
||||
$form.get(0).submit();
|
||||
}
|
||||
};
|
||||
|
||||
function plaidSuccessHandler(public_token, metadata) {
|
||||
$('#secured_by_plaid').hide()
|
||||
var $form = $('.payment-form');
|
||||
|
||||
$form.append($('<input type="hidden" name="plaidPublicToken"/>').val(public_token));
|
||||
$form.append($('<input type="hidden" name="plaidAccountId"/>').val(metadata.account_id));
|
||||
$('#plaid_linked_status').text('{{ trans('texts.plaid_linked_status') }}'.replace(':bank', metadata.institution.name));
|
||||
$('#manual_container').fadeOut();
|
||||
$('#plaid_linked').show();
|
||||
$('#plaid_link_button').hide();
|
||||
$('[name=account_holder_type],#account_holder_name').removeAttr('required');
|
||||
|
||||
|
||||
var payNowBtn = $('#pay_now_button');
|
||||
if(payNowBtn.length) {
|
||||
payNowBtn.show();
|
||||
$('#add_account_button').hide();
|
||||
}
|
||||
};
|
||||
</script>
|
52
resources/views/payments/tokenization_wepay.blade.php
Normal file
52
resources/views/payments/tokenization_wepay.blade.php
Normal file
@ -0,0 +1,52 @@
|
||||
<script type="text/javascript" src="https://static.wepay.com/min/js/tokenization.v2.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var countries = {!! $countries->pluck('iso_3166_2','id') !!};
|
||||
WePay.set_endpoint('{{ WEPAY_ENVIRONMENT }}');
|
||||
$('.payment-form').submit(function(event) {
|
||||
var data = {
|
||||
client_id: {{ WEPAY_CLIENT_ID }},
|
||||
user_name: $('#first_name').val() + ' ' + $('#last_name').val(),
|
||||
email: $('#email').val(),
|
||||
cc_number: $('#card_number').val(),
|
||||
cvv: $('#cvv').val(),
|
||||
expiration_month: $('#expiration_month').val(),
|
||||
expiration_year: $('#expiration_year').val(),
|
||||
address: {
|
||||
address1: $('#address1').val(),
|
||||
address2: $('#address2').val(),
|
||||
city: $('#city').val(),
|
||||
country: countries[$("#country_id").val()]
|
||||
}
|
||||
};
|
||||
|
||||
if(data.address.country == 'US') {
|
||||
data.address.zip = $('#postal_code').val();
|
||||
} else {
|
||||
data.address.postcode = $('#postal_code').val();
|
||||
}
|
||||
// Not including state/province, since WePay wants 2-letter codes and users enter the full name
|
||||
|
||||
var response = WePay.credit_card.create(data, function(response) {
|
||||
var $form = $('.payment-form');
|
||||
|
||||
if (response.error) {
|
||||
// Show the errors on the form
|
||||
var error = response.error_description;
|
||||
$form.find('button').prop('disabled', false);
|
||||
$('#js-error-message').text(error).fadeIn();
|
||||
} else {
|
||||
// response contains id and card, which contains additional card details
|
||||
var token = response.credit_card_id;
|
||||
// Insert the token into the form so it gets submitted to the server
|
||||
$form.append($('<input type="hidden" name="sourceToken"/>').val(token));
|
||||
// and submit
|
||||
$form.get(0).submit();
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent the form from submitting with the default action
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user