Skip to content

Commit

Permalink
feat: adiciona método para pagar fatura existente com cartão de crédito
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewalkermo committed Sep 12, 2024
1 parent 2ff9727 commit b642bb4
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 14 deletions.
12 changes: 12 additions & 0 deletions src/Contracts/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,17 @@ public function refundInvoice(Invoice $invoice): Invoice;
*
* @return string
*/

/**
* Charge an invoice with a credit card
*
* @param \Potelo\MultiPayment\Models\Invoice $invoice
* @return \Potelo\MultiPayment\Models\Invoice
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
* @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException
*/
public function chargeInvoiceWithCreditCard(Invoice $invoice): Invoice;

public function __toString();
}
2 changes: 1 addition & 1 deletion src/Exceptions/MultiPaymentException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Potelo\MultiPayment\Exceptions;

abstract class MultiPaymentException extends \Exception
class MultiPaymentException extends \Exception
{
//
}
1 change: 1 addition & 0 deletions src/Facades/MultiPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* @method static CustomerBuilder newCustomer()
* @method static CreditCardBuilder newCreditCard()
* @method static \Potelo\MultiPayment\MultiPayment setGateway($gateway)
* @method static Invoice chargeInvoiceWithCreditCard($invoice, ?string $creditCardToken = null, ?string $creditCardId = null)
*/
class MultiPayment extends Facade
{
Expand Down
73 changes: 60 additions & 13 deletions src/Gateways/IuguGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,7 @@ public function createInvoice(Invoice $invoice): Invoice
$invoice->creditCard = $this->createCreditCard($invoice->creditCard);
}
$iuguInvoiceData['customer_payment_method_id'] = $invoice->creditCard->id;
try {
$iuguCharge = \Iugu_Charge::create($iuguInvoiceData);
} catch (\Exception $e) {
throw new GatewayException($e->getMessage());
}
if ($iuguCharge->errors) {
throw new GatewayException('Error charging invoice', $iuguCharge->errors);
} elseif (!$iuguCharge->success) {
$exception = new ChargingException('Error charging invoice: ' . $iuguCharge->info_message);
$exception->chargeResponse = $iuguCharge;
throw $exception;
}
$iuguInvoice = $iuguCharge->invoice();
$iuguInvoice = $this->chargeIuguInvoice($iuguInvoiceData);
} else {
try {
$iuguInvoice = \Iugu_Invoice::create($iuguInvoiceData);
Expand Down Expand Up @@ -486,4 +474,63 @@ private function parseInvoice($iuguInvoice, ?Invoice $invoice = null): Invoice

return $invoice;
}

/**
* @inheritDoc
* @param \Potelo\MultiPayment\Models\Invoice $invoice
* @return \Potelo\MultiPayment\Models\Invoice
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
* @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException
*/
public function chargeInvoiceWithCreditCard(Invoice $invoice): Invoice
{
if (empty($invoice->id)) {
throw ModelAttributeValidationException::required('Invoice', 'id');
}

if (empty($invoice->creditCard)) {
throw ModelAttributeValidationException::required('Invoice', 'creditCard');
}

if (empty($invoice->creditCard->token) && empty($invoice->creditCard->id)) {
throw new ModelAttributeValidationException('Credit card token or id is required');
}

$iuguInvoiceData = [];
$iuguInvoiceData['invoice_id'] = $invoice->id;

if (!empty($invoice->creditCard->id)) {
$iuguInvoiceData['customer_payment_method_id'] = $invoice->creditCard->id;
} else {
$iuguInvoiceData['token'] = $invoice->creditCard->token;
}

$iuguInvoice = $this->chargeIuguInvoice($iuguInvoiceData);

return $this->parseInvoice($iuguInvoice, $invoice);
}

/**
* @param array $iuguInvoiceData
* @return mixed
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
*/
private function chargeIuguInvoice(array $iuguInvoiceData)
{
try {
$iuguCharge = \Iugu_Charge::create($iuguInvoiceData);
} catch (\Exception $e) {
throw new GatewayException($e->getMessage());
}
if ($iuguCharge->errors) {
throw new GatewayException('Error charging invoice', $iuguCharge->errors);
} elseif (!$iuguCharge->success) {
$exception = new ChargingException('Error charging invoice: ' . $iuguCharge->info_message);
$exception->chargeResponse = $iuguCharge;
throw $exception;
}
return $iuguCharge->invoice();
}
}
19 changes: 19 additions & 0 deletions src/Models/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,23 @@ public function refund(): Invoice
$gateway = ConfigurationHelper::resolveGateway($this->gateway);
return $gateway->refundInvoice($this);
}

/**
* Charge invoice with credit card
*
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
* @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\ConfigurationException
*/
public function chargeInvoiceWithCreditCard(?CreditCard $creditCard = null): Invoice
{
if (!empty($creditCard)) {
$this->creditCard = $creditCard;
}

$gateway = ConfigurationHelper::resolveGateway($this->gateway);

return $gateway->chargeInvoiceWithCreditCard($this);
}
}
47 changes: 47 additions & 0 deletions src/MultiPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Potelo\MultiPayment;

use Potelo\MultiPayment\Exceptions\MultiPaymentException;
use Potelo\MultiPayment\Models\CreditCard;
use Potelo\MultiPayment\Models\Invoice;
use Potelo\MultiPayment\Models\Customer;
use Potelo\MultiPayment\Contracts\Gateway;
Expand Down Expand Up @@ -125,4 +127,49 @@ public function refundInvoice(string $id, ?int $partialValueCents = null): Invoi
return $invoice->refund();

}

/**
* Charge invoice with credit card
*
* @param Invoice|string $invoice
* @param string|null $creditCardToken
* @param string|null $creditCardId
*
* @return \Potelo\MultiPayment\Models\Invoice
*
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\ConfigurationException
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
* @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException
* @throws \Potelo\MultiPayment\Exceptions\MultiPaymentException
*/
public function chargeInvoiceWithCreditCard($invoice, ?string $creditCardToken = null, ?string $creditCardId = null): Invoice
{
if (is_string($invoice)) {
$invoiceInstance = new Invoice();
$invoiceInstance->id = $invoice;
$invoice = $invoiceInstance;
}

if (!empty($creditCardToken) && !empty($creditCardId)) {
throw new MultiPaymentException('"creditCardToken" and "creditCardId" are mutually exclusive');
}

if (!empty($creditCardToken)) {
$invoice->creditCard = new CreditCard();
$invoice->creditCard->token = $creditCardToken;
} elseif (!empty($creditCardId)) {
$invoice->creditCard = new CreditCard();
$invoice->creditCard->id = $creditCardId;
}

if (empty($invoice->creditCard)) {
throw new MultiPaymentException('"invoice->creditCard" or "creditCardToken" or "creditCardId" must be provided');
}

$invoice->gateway = $this->gateway;
$invoice->creditCard->gateway = $this->gateway;

return $invoice->chargeInvoiceWithCreditCard();
}
}
98 changes: 98 additions & 0 deletions tests/Unit/MultiPaymentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Potelo\MultiPayment\Tests\Unit;

use Potelo\MultiPayment\Models\CreditCard;
use Potelo\MultiPayment\Tests\TestCase;
use Potelo\MultiPayment\Models\Invoice;
use Potelo\MultiPayment\Facades\MultiPayment;
Expand Down Expand Up @@ -131,4 +132,101 @@ public function shouldRefundInvoiceDataProvider(): array
],
];
}


/**
* Test if can refund the invoice
*
* @dataProvider shouldChargeInvoiceWithCreditCard
*
* @param string $gateway
* @param array $data
* @param string $status
* @param string $creditCardDataMethod
* @return void
* @throws \Potelo\MultiPayment\Exceptions\ChargingException
* @throws \Potelo\MultiPayment\Exceptions\ConfigurationException
* @throws \Potelo\MultiPayment\Exceptions\GatewayException
* @throws \Potelo\MultiPayment\Exceptions\GatewayNotAvailableException
* @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException
* @throws \Potelo\MultiPayment\Exceptions\MultiPaymentException
*/
public function testShouldChargeInvoiceWithCreditCard(string $gateway, array $data, string $status, string $creditCardDataMethod)
{
$multiPayment = new \Potelo\MultiPayment\MultiPayment($gateway);

$invoiceBuilder = $multiPayment->newInvoice();
$invoiceBuilder->addCustomer(
$data['customer']['name'] ?? null,
$data['customer']['email'] ?? null,
$data['customer']['taxDocument'] ?? null,
$data['customer']['birthDate'] ?? null,
$data['customer']['phoneArea'] ?? null,
$data['customer']['phoneNumber'] ?? null
);
foreach ($data['items'] as $item) {
$invoiceBuilder->addItem($item['description'], $item['price'], $item['quantity']);
}
$invoice = $invoiceBuilder->create();
sleep(3);

if ($creditCardDataMethod == 'creditCard') {
$invoice->creditCard = new CreditCard();
$invoice->creditCard->fill(self::creditCard());
$invoice->creditCard->customer = $invoice->customer;
$invoice->creditCard->save();

$invoice = $multiPayment->chargeInvoiceWithCreditCard($invoice);
} elseif ($creditCardDataMethod == 'token') {
$creditCardToken = self::iuguCreditCardToken();
$invoice = $multiPayment->chargeInvoiceWithCreditCard($invoice->id, $creditCardToken);
} elseif ($creditCardDataMethod == 'id') {
$creditCard = new CreditCard();
$creditCard->fill(self::creditCard());
$creditCard->customer = $invoice->customer;
$creditCard->save();
$invoice = $multiPayment->chargeInvoiceWithCreditCard($invoice->id, null, $creditCard->id);
}

$this->assertEquals($status, $invoice->status);
}

/**
* @return array
*/
public function shouldChargeInvoiceWithCreditCard(): array
{
return [
'iugu - credit card object' => [
'gateway' => 'iugu',
'data' => [
'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]],
'customer' => self::customerWithoutAddress(),
'paymentMethod' => 'credit_card',
],
'status' => Invoice::STATUS_PAID,
'creditCardDataMethod' => 'creditCard',
],
'iugu - credit card token' => [
'gateway' => 'iugu',
'data' => [
'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]],
'customer' => self::customerWithoutAddress(),
'paymentMethod' => 'credit_card',
],
'status' => Invoice::STATUS_PAID,
'creditCardDataMethod' => 'token',
],
'iugu - credit card id' => [
'gateway' => 'iugu',
'data' => [
'items' => [['description' => 'Teste', 'quantity' => 1, 'price' => 10000,]],
'customer' => self::customerWithoutAddress(),
'paymentMethod' => 'credit_card',
],
'status' => Invoice::STATUS_PAID,
'creditCardDataMethod' => 'id',
],
];
}
}

0 comments on commit b642bb4

Please sign in to comment.