2017-01-30 20:40:43 +01:00
|
|
|
<?php
|
2016-06-20 16:14:43 +02:00
|
|
|
|
2017-01-30 20:40:43 +01:00
|
|
|
namespace App\Ninja\PaymentDrivers;
|
|
|
|
|
|
|
|
use Braintree\Customer;
|
2016-06-20 16:14:43 +02:00
|
|
|
use Exception;
|
|
|
|
use Session;
|
2017-08-11 09:55:54 +02:00
|
|
|
use Utils;
|
2017-03-29 20:45:41 +02:00
|
|
|
use App\Models\GatewayType;
|
2017-08-31 14:55:15 +02:00
|
|
|
use App\Models\PaymentType;
|
2016-06-20 16:14:43 +02:00
|
|
|
|
|
|
|
class BraintreePaymentDriver extends BasePaymentDriver
|
|
|
|
{
|
|
|
|
protected $customerReferenceParam = 'customerId';
|
|
|
|
protected $sourceReferenceParam = 'paymentMethodToken';
|
2017-05-16 11:20:35 +02:00
|
|
|
public $canRefundPayments = true;
|
2016-06-20 16:14:43 +02:00
|
|
|
|
2016-06-22 20:42:09 +02:00
|
|
|
public function gatewayTypes()
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
|
|
|
$types = [
|
|
|
|
GATEWAY_TYPE_CREDIT_CARD,
|
|
|
|
GATEWAY_TYPE_TOKEN,
|
|
|
|
];
|
|
|
|
|
2016-06-22 20:42:09 +02:00
|
|
|
if ($this->accountGateway && $this->accountGateway->getPayPalEnabled()) {
|
2016-06-20 16:14:43 +02:00
|
|
|
$types[] = GATEWAY_TYPE_PAYPAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $types;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function tokenize()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-07-21 14:35:23 +02:00
|
|
|
public function startPurchase($input = false, $sourceId = false)
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
|
|
|
$data = parent::startPurchase($input, $sourceId);
|
|
|
|
|
|
|
|
if ($this->isGatewayType(GATEWAY_TYPE_PAYPAL)) {
|
2016-07-21 14:35:23 +02:00
|
|
|
/*
|
|
|
|
if ( ! $sourceId || empty($input['device_data'])) {
|
|
|
|
throw new Exception();
|
|
|
|
}
|
|
|
|
|
|
|
|
Session::put($this->invitation->id . 'device_data', $input['device_data']);
|
|
|
|
*/
|
|
|
|
|
2016-06-20 16:14:43 +02:00
|
|
|
$data['details'] = ! empty($input['device_data']) ? json_decode($input['device_data']) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function checkCustomerExists($customer)
|
|
|
|
{
|
2017-01-30 17:05:31 +01:00
|
|
|
if (! parent::checkCustomerExists($customer)) {
|
2016-06-20 16:14:43 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$customer = $this->gateway()->findCustomer($customer->token)
|
|
|
|
->send()
|
|
|
|
->getData();
|
|
|
|
|
2017-01-30 20:40:43 +01:00
|
|
|
return $customer instanceof Customer;
|
2016-06-20 16:14:43 +02:00
|
|
|
}
|
|
|
|
|
2017-03-29 20:45:41 +02:00
|
|
|
protected function paymentUrl($gatewayTypeAlias)
|
|
|
|
{
|
|
|
|
$url = parent::paymentUrl($gatewayTypeAlias);
|
|
|
|
|
|
|
|
if (GatewayType::getIdFromAlias($gatewayTypeAlias) === GATEWAY_TYPE_PAYPAL) {
|
|
|
|
$url .= '#braintree_paypal';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $url;
|
|
|
|
}
|
|
|
|
|
2016-07-21 14:35:23 +02:00
|
|
|
protected function paymentDetails($paymentMethod = false)
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
|
|
|
$data = parent::paymentDetails($paymentMethod);
|
|
|
|
|
|
|
|
$deviceData = array_get($this->input, 'device_data') ?: Session::get($this->invitation->id . 'device_data');
|
|
|
|
|
|
|
|
if ($deviceData) {
|
|
|
|
$data['device_data'] = $deviceData;
|
|
|
|
}
|
|
|
|
|
2016-06-23 19:17:02 +02:00
|
|
|
if ($this->isGatewayType(GATEWAY_TYPE_PAYPAL, $paymentMethod)) {
|
2016-06-20 16:14:43 +02:00
|
|
|
$data['ButtonSource'] = 'InvoiceNinja_SP';
|
|
|
|
}
|
|
|
|
|
2017-01-30 17:05:31 +01:00
|
|
|
if (! $paymentMethod && ! empty($this->input['sourceToken'])) {
|
2016-06-20 16:14:43 +02:00
|
|
|
$data['token'] = $this->input['sourceToken'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function createToken()
|
|
|
|
{
|
2017-08-11 09:55:54 +02:00
|
|
|
$data = $this->paymentDetails();
|
|
|
|
|
2016-06-20 16:14:43 +02:00
|
|
|
if ($customer = $this->customer()) {
|
|
|
|
$customerReference = $customer->token;
|
|
|
|
} else {
|
|
|
|
$tokenResponse = $this->gateway()->createCustomer(['customerData' => $this->customerData()])->send();
|
|
|
|
if ($tokenResponse->isSuccessful()) {
|
|
|
|
$customerReference = $tokenResponse->getCustomerData()->id;
|
|
|
|
} else {
|
2017-08-11 09:59:12 +02:00
|
|
|
Utils::logError('Failed to create Braintree customer: ' . $tokenResponse->getMessage());
|
2016-06-20 16:14:43 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($customerReference) {
|
|
|
|
$data['customerId'] = $customerReference;
|
|
|
|
|
|
|
|
if ($this->isGatewayType(GATEWAY_TYPE_PAYPAL)) {
|
|
|
|
$data['paymentMethodNonce'] = $this->input['sourceToken'];
|
|
|
|
}
|
|
|
|
|
|
|
|
$tokenResponse = $this->gateway->createPaymentMethod($data)->send();
|
|
|
|
if ($tokenResponse->isSuccessful()) {
|
|
|
|
$this->tokenResponse = $tokenResponse->getData()->paymentMethod;
|
|
|
|
} else {
|
2017-08-11 09:59:12 +02:00
|
|
|
Utils::logError('Failed to create Braintree token: ' . $tokenResponse->getMessage());
|
2016-06-20 16:14:43 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::createToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function customerData()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'firstName' => array_get($this->input, 'first_name') ?: $this->contact()->first_name,
|
|
|
|
'lastName' => array_get($this->input, 'last_name') ?: $this->contact()->last_name,
|
|
|
|
'company' => $this->client()->name,
|
|
|
|
'email' => $this->contact()->email,
|
|
|
|
'phone' => $this->contact()->phone,
|
2017-01-30 20:40:43 +01:00
|
|
|
'website' => $this->client()->website,
|
2016-06-20 16:14:43 +02:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function creatingCustomer($customer)
|
|
|
|
{
|
|
|
|
$customer->token = $this->tokenResponse->customerId;
|
|
|
|
|
|
|
|
return $customer;
|
|
|
|
}
|
|
|
|
|
2016-07-21 14:35:23 +02:00
|
|
|
protected function creatingPaymentMethod($paymentMethod)
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
|
|
|
$response = $this->tokenResponse;
|
|
|
|
|
|
|
|
$paymentMethod->source_reference = $response->token;
|
|
|
|
|
|
|
|
if ($this->isGatewayType(GATEWAY_TYPE_CREDIT_CARD)) {
|
2017-08-31 14:55:15 +02:00
|
|
|
$paymentMethod->payment_type_id = PaymentType::parseCardType($response->cardType);
|
2016-06-20 16:14:43 +02:00
|
|
|
$paymentMethod->last4 = $response->last4;
|
|
|
|
$paymentMethod->expiration = $response->expirationYear . '-' . $response->expirationMonth . '-01';
|
|
|
|
} elseif ($this->isGatewayType(GATEWAY_TYPE_PAYPAL)) {
|
|
|
|
$paymentMethod->email = $response->email;
|
|
|
|
$paymentMethod->payment_type_id = PAYMENT_TYPE_PAYPAL;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $paymentMethod;
|
|
|
|
}
|
|
|
|
|
2016-07-21 14:35:23 +02:00
|
|
|
public function removePaymentMethod($paymentMethod)
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
2016-06-24 14:40:10 +02:00
|
|
|
parent::removePaymentMethod($paymentMethod);
|
|
|
|
|
2016-06-20 16:14:43 +02:00
|
|
|
$response = $this->gateway()->deletePaymentMethod([
|
2017-01-30 20:40:43 +01:00
|
|
|
'token' => $paymentMethod->source_reference,
|
2016-06-20 16:14:43 +02:00
|
|
|
])->send();
|
|
|
|
|
|
|
|
if ($response->isSuccessful()) {
|
2016-06-24 14:40:10 +02:00
|
|
|
return true;
|
2016-06-20 16:14:43 +02:00
|
|
|
} else {
|
|
|
|
throw new Exception($response->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-21 14:35:23 +02:00
|
|
|
protected function attemptVoidPayment($response, $payment, $amount)
|
2016-06-20 16:14:43 +02:00
|
|
|
{
|
2017-01-30 17:05:31 +01:00
|
|
|
if (! parent::attemptVoidPayment($response, $payment, $amount)) {
|
2016-06-20 16:14:43 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$data = $response->getData();
|
|
|
|
|
|
|
|
if ($data instanceof \Braintree\Result\Error) {
|
|
|
|
$error = $data->errors->deepAll()[0];
|
|
|
|
if ($error && $error->code == 91506) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function createTransactionToken()
|
|
|
|
{
|
|
|
|
return $this->gateway()
|
|
|
|
->clientToken()
|
|
|
|
->send()
|
|
|
|
->getToken();
|
|
|
|
}
|
2017-09-03 09:35:28 +02:00
|
|
|
|
|
|
|
public function isValid()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
$this->createTransactionToken();
|
|
|
|
return true;
|
|
|
|
} catch (Exception $exception) {
|
|
|
|
return get_class($exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-20 16:14:43 +02:00
|
|
|
}
|