1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00
invoiceninja/app/Ninja/PaymentDrivers/BraintreePaymentDriver.php

227 lines
6.4 KiB
PHP
Raw Normal View History

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;
use Utils;
use App\Models\GatewayType;
use App\Models\PaymentType;
2016-06-20 16:14:43 +02:00
class BraintreePaymentDriver extends BasePaymentDriver
{
protected $customerReferenceParam = 'customerId';
protected $sourceReferenceParam = 'paymentMethodToken';
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
}
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()
{
$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 {
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 {
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)) {
$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();
}
public function isValid()
{
try {
$this->createTransactionToken();
return true;
} catch (Exception $exception) {
return get_class($exception);
}
}
2016-06-20 16:14:43 +02:00
}