1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00
invoiceninja/app/Ninja/PaymentDrivers/WePayPaymentDriver.php

309 lines
10 KiB
PHP
Raw Normal View History

2016-06-20 16:14:43 +02:00
<?php namespace App\Ninja\PaymentDrivers;
2016-06-21 18:10:22 +02:00
use Session;
use Utils;
2016-06-23 15:15:52 +02:00
use App\Models\Payment;
2016-06-21 11:07:16 +02:00
use Exception;
2016-06-20 16:14:43 +02:00
class WePayPaymentDriver extends BasePaymentDriver
{
2016-06-26 11:59:42 +02:00
protected $sourceReferenceParam = 'accessToken';
2016-06-22 20:42:09 +02:00
public function gatewayTypes()
2016-06-20 16:14:43 +02:00
{
2016-06-22 20:42:09 +02:00
$types = [
2016-06-20 16:14:43 +02:00
GATEWAY_TYPE_CREDIT_CARD,
GATEWAY_TYPE_TOKEN
];
2016-06-22 20:42:09 +02:00
if ($this->accountGateway && $this->accountGateway->getAchEnabled()) {
$types[] = GATEWAY_TYPE_BANK_TRANSFER;
}
return $types;
2016-06-20 16:14:43 +02:00
}
2016-06-22 11:22:38 +02:00
/*
2016-06-20 21:26:48 +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_BANK_TRANSFER)) {
if ( ! $sourceId) {
throw new Exception();
}
}
return $data;
}
2016-06-22 11:22:38 +02:00
*/
2016-06-20 16:14:43 +02:00
public function tokenize()
{
return true;
}
protected function checkCustomerExists($customer)
{
return true;
}
public function rules()
{
$rules = parent::rules();
if ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER)) {
$rules = array_merge($rules, [
'authorize_ach' => 'required',
'tos_agree' => 'required',
]);
}
return $rules;
}
protected function paymentDetails($paymentMethod = false)
{
$data = parent::paymentDetails($paymentMethod);
2016-06-21 18:10:22 +02:00
if ($transactionId = Session::get($this->invitation->id . 'payment_ref')) {
2016-06-20 16:14:43 +02:00
$data['transaction_id'] = $transactionId;
}
$data['applicationFee'] = $this->calculateApplicationFee($data['amount']);
$data['feePayer'] = WEPAY_FEE_PAYER;
$data['callbackUri'] = $this->accountGateway->getWebhookUrl();
2016-06-26 12:45:50 +02:00
if ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER, $paymentMethod)) {
2016-06-20 16:14:43 +02:00
$data['paymentMethodType'] = 'payment_bank';
}
return $data;
}
2016-06-21 18:10:22 +02:00
public function createToken()
{
$wepay = Utils::setupWePay($this->accountGateway);
$token = intval($this->input['sourceToken']);
if ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER)) {
// Persist bank details
$this->tokenResponse = $wepay->request('/payment_bank/persist', array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'payment_bank_id' => $token,
));
} else {
// Authorize credit card
$tokenResponse = $wepay->request('credit_card/authorize', array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'credit_card_id' => $token,
));
// Update the callback uri and get the card details
$tokenResponse = $wepay->request('credit_card/modify', array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'credit_card_id' => $token,
'auto_update' => WEPAY_AUTO_UPDATE,
'callback_uri' => $this->accountGateway->getWebhookUrl(),
));
$this->tokenResponse = $wepay->request('credit_card', array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'credit_card_id' => $token,
));
}
return parent::createToken();
}
/*
public function creatingCustomer($customer)
{
if ($gatewayResponse instanceof \Omnipay\WePay\Message\CustomCheckoutResponse) {
$wepay = \Utils::setupWePay($accountGateway);
$paymentMethodType = $gatewayResponse->getData()['payment_method']['type'];
$gatewayResponse = $wepay->request($paymentMethodType, array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
$paymentMethodType.'_id' => $gatewayResponse->getData()['payment_method'][$paymentMethodType]['id'],
));
}
}
*/
protected function creatingPaymentMethod($paymentMethod)
{
$source = $this->tokenResponse;
if ($this->isGatewayType(GATEWAY_TYPE_BANK_TRANSFER)) {
$paymentMethod->payment_type_id = PAYMENT_TYPE_ACH;
$paymentMethod->last4 = $source->account_last_four;
$paymentMethod->bank_name = $source->bank_name;
$paymentMethod->source_reference = $source->payment_bank_id;
switch($source->state) {
case 'new':
case 'pending':
$paymentMethod->status = 'new';
break;
case 'authorized':
$paymentMethod->status = 'verified';
break;
}
} else {
$paymentMethod->last4 = $source->last_four;
$paymentMethod->payment_type_id = $this->parseCardType($source->credit_card_name);
$paymentMethod->expiration = $source->expiration_year . '-' . $source->expiration_month . '-01';
$paymentMethod->source_reference = $source->credit_card_id;
}
return $paymentMethod;
}
2016-06-20 16:14:43 +02:00
public function removePaymentMethod($paymentMethod)
{
2016-06-24 14:40:10 +02:00
parent::removePaymentMethod($paymentMethod);
2016-06-20 16:14:43 +02:00
$wepay = Utils::setupWePay($this->accountGateway);
2016-06-21 18:10:22 +02:00
$response = $wepay->request('/credit_card/delete', [
2016-06-20 16:14:43 +02:00
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'credit_card_id' => intval($paymentMethod->source_reference),
]);
2016-06-21 18:10:22 +02:00
if ($response->state == 'deleted') {
2016-06-24 14:40:10 +02:00
return true;
2016-06-20 16:14:43 +02:00
} else {
2016-06-22 11:22:38 +02:00
throw new Exception(trans('texts.failed_remove_payment_method'));
2016-06-20 16:14:43 +02:00
}
}
protected function refundDetails($payment, $amount)
{
2016-06-21 18:10:22 +02:00
$data = parent::refundDetails($payment, $amount);
2016-06-20 16:14:43 +02:00
$data['refund_reason'] = 'Refund issued by merchant.';
// WePay issues a full refund when no amount is set. If an amount is set, it will try
// to issue a partial refund without refunding any fees. However, the Stripe driver
// (but not the API) requires the amount parameter to be set no matter what.
if ($data['amount'] == $payment->getCompletedAmount()) {
unset($data['amount']);
}
return $data;
}
protected function attemptVoidPayment($response, $payment, $amount)
{
if ( ! parent::attemptVoidPayment($response, $payment, $amount)) {
return false;
}
return $response->getCode() == 4004;
}
private function calculateApplicationFee($amount)
{
2016-06-26 18:38:36 +02:00
$fee = (WEPAY_APP_FEE_MULTIPLIER * $amount) + WEPAY_APP_FEE_FIXED;
2016-06-20 16:14:43 +02:00
return floor(min($fee, $amount * 0.2));// Maximum fee is 20% of the amount.
}
2016-06-23 15:27:54 +02:00
public function handleWebHook($input)
2016-06-23 15:15:52 +02:00
{
2016-06-24 17:15:51 +02:00
$accountGateway = $this->accountGateway;
2016-06-23 15:15:52 +02:00
$accountId = $accountGateway->account_id;
foreach (array_keys($input) as $key) {
if ('_id' == substr($key, -3)) {
$objectType = substr($key, 0, -3);
$objectId = $input[$key];
break;
}
}
if (!isset($objectType)) {
throw new Exception('Could not find object id parameter');
}
if ($objectType == 'credit_card') {
$paymentMethod = PaymentMethod::scope(false, $accountId)->where('source_reference', '=', $objectId)->first();
if (!$paymentMethod) {
throw new Exception('Unknown payment method');
}
$wepay = Utils::setupWePay($accountGateway);
$source = $wepay->request('credit_card', array(
'client_id' => WEPAY_CLIENT_ID,
'client_secret' => WEPAY_CLIENT_SECRET,
'credit_card_id' => intval($objectId),
));
if ($source->state == 'deleted') {
$paymentMethod->delete();
} else {
2016-06-28 20:21:54 +02:00
//$this->paymentService->convertPaymentMethodFromWePay($source, null, $paymentMethod)->save();
2016-06-23 15:15:52 +02:00
}
return 'Processed successfully';
} elseif ($objectType == 'account') {
$config = $accountGateway->getConfig();
if ($config->accountId != $objectId) {
throw new Exception('Unknown account');
}
$wepay = Utils::setupWePay($accountGateway);
$wepayAccount = $wepay->request('account', array(
'account_id' => intval($objectId),
));
if ($wepayAccount->state == 'deleted') {
$accountGateway->delete();
} else {
$config->state = $wepayAccount->state;
$accountGateway->setConfig($config);
$accountGateway->save();
}
return array('message' => 'Processed successfully');
} elseif ($objectType == 'checkout') {
$payment = Payment::scope(false, $accountId)->where('transaction_reference', '=', $objectId)->first();
if (!$payment) {
throw new Exception('Unknown payment');
}
$wepay = Utils::setupWePay($accountGateway);
$checkout = $wepay->request('checkout', array(
'checkout_id' => intval($objectId),
));
if ($checkout->state == 'refunded') {
$payment->recordRefund();
} elseif (!empty($checkout->refund) && !empty($checkout->refund->amount_refunded) && ($checkout->refund->amount_refunded - $payment->refunded) > 0) {
$payment->recordRefund($checkout->refund->amount_refunded - $payment->refunded);
}
if ($checkout->state == 'captured') {
$payment->markComplete();
} elseif ($checkout->state == 'cancelled') {
$payment->markCancelled();
} elseif ($checkout->state == 'failed') {
$payment->markFailed();
}
return 'Processed successfully';
} else {
return 'Ignoring event';
}
}
2016-06-20 16:14:43 +02:00
}