From 2b5a2dc88d4a2104c963682623f60354392f7b2c Mon Sep 17 00:00:00 2001 From: Michael de Oliveira Ferreira Date: Fri, 6 Oct 2023 00:52:02 -0300 Subject: [PATCH 1/2] feature: create baas billet --- src/Clients/CelcoinBAASBillet.php | 35 +++ src/Rules/BAAS/Billet.php | 45 ++++ src/Types/BAAS/Billet.php | 37 ++++ src/Types/BAAS/BilletDebtor.php | 25 +++ src/Types/BAAS/BilletDiscount.php | 18 ++ src/Types/BAAS/BilletInstruction.php | 19 ++ src/Types/BAAS/BilletReceiver.php | 18 ++ src/Types/BAAS/BilletSplit.php | 20 ++ .../BAAS/CelcoinBASSBilletTest.php | 205 ++++++++++++++++++ 9 files changed, 422 insertions(+) create mode 100644 src/Clients/CelcoinBAASBillet.php create mode 100644 src/Rules/BAAS/Billet.php create mode 100644 src/Types/BAAS/Billet.php create mode 100644 src/Types/BAAS/BilletDebtor.php create mode 100644 src/Types/BAAS/BilletDiscount.php create mode 100644 src/Types/BAAS/BilletInstruction.php create mode 100644 src/Types/BAAS/BilletReceiver.php create mode 100644 src/Types/BAAS/BilletSplit.php create mode 100644 tests/Integration/BAAS/CelcoinBASSBilletTest.php diff --git a/src/Clients/CelcoinBAASBillet.php b/src/Clients/CelcoinBAASBillet.php new file mode 100644 index 0000000..487103e --- /dev/null +++ b/src/Clients/CelcoinBAASBillet.php @@ -0,0 +1,35 @@ +toArray(), BilletRules::rules()); + return $this->post(self::CREATE_BILLET_URL, $data); + } + + /** + * @throws RequestException + */ + public function getBillet($transaction_id = null, $external_id = null) + { + return $this->get(self::GET_BILLET_URL, [ + 'transactionId' => $transaction_id, + 'externalId' => $external_id, + ]); + } +} \ No newline at end of file diff --git a/src/Rules/BAAS/Billet.php b/src/Rules/BAAS/Billet.php new file mode 100644 index 0000000..a5a5719 --- /dev/null +++ b/src/Rules/BAAS/Billet.php @@ -0,0 +1,45 @@ + ['required'], + 'merchantCategoryCode' => ['sometimes', 'required'], + 'expirationAfterPayment' => ['boolean'], + 'duedate' => ['required', 'date'], + 'amount' => ['required', 'numeric:0,2'], + 'key' => ['sometimes', 'nullable'], + 'debtor' => ['required', 'array'], + 'debtor.name' => ['required'], + 'debtor.document' => ['required', 'numeric'], + 'debtor.postalCode' => ['required', 'numeric'], + 'debtor.publicArea' => ['required'], + 'debtor.number' => ['required', 'numeric'], + 'debtor.complement' => ['nullable'], + 'debtor.neighborhood' => ['required'], + 'debtor.city' => ['required'], + 'debtor.state' => ['required'], + 'receiver.document' => ['required','numeric'], + 'receiver.account' => ['required','numeric'], + 'instructions' => ['sometimes', 'array'], + 'instructions.discounts' => ['required_with:instructions','array'], + 'instructions.discounts.*.amount' => ['nullable','numeric:0,2'], + 'instructions.discounts.*.modality' => ['nullable'], + 'instructions.discounts.*.limitDate' => ['nullable', 'date'], + 'instructions.fine' => ['nullable','numeric:0,2'], + 'instructions.interest' => ['nullable','numeric:0,2'], + 'split' => ['sometimes', 'array'], + 'split.*.account' => ['nullable', 'numeric'], + 'split.*.document' => ['nullable', 'numeric'], + 'split.*.percent' => ['nullable', 'numeric'], + 'split.*.amount' => ['nullable', 'numeric'], + 'split.*.aggregatePayment' => ['nullable', 'boolean'], + ]; + } +} diff --git a/src/Types/BAAS/Billet.php b/src/Types/BAAS/Billet.php new file mode 100644 index 0000000..19f06e3 --- /dev/null +++ b/src/Types/BAAS/Billet.php @@ -0,0 +1,37 @@ + + */ + public ?array $instructions; + /** + * @var array + */ + public ?array $split; + + + public function __construct(array $data = []) + { + parent::__construct($data); + } +} diff --git a/src/Types/BAAS/BilletDebtor.php b/src/Types/BAAS/BilletDebtor.php new file mode 100644 index 0000000..153f0d0 --- /dev/null +++ b/src/Types/BAAS/BilletDebtor.php @@ -0,0 +1,25 @@ + GlobalStubs::loginResponse(), + sprintf( + '%s%s', + config('api_url'), + CelcoinBAASBillet::CREATE_BILLET_URL, + ) => self::successCreateBilletStub(), + ], + ); + + $billet = new CelcoinBAASBillet(); + $result = $billet->createBillet($this->billetBodyRequest()); + + $this->assertEquals('SUCCESS', $result['status']); + $this->assertEquals('ce9b8d9b-0617-42e1-b500-80bf9d8154cf', $result['body']['transactionId']); + } + + public static function billetBodyRequest(): Billet + { + return new Billet([ + "externalId" => "externalId1", + "expirationAfterPayment" => 1, + "merchantCatagoryCode" => "0000", + "duedate" => "2023-12-30T00:00:00.0000000", + "amount" => 12.5, + "key" => "testepix@celcoin.com.br", + "debtor" => new BilletDebtor([ + "name" => "Marcos Samuel Duarte", + "document" => "49188474801", + "postalCode" => "06463035", + "publicArea" => "Rua Mãe D'Água", + "complement" => null, + "number" => "1004", + "neighborhood" => "Jardim Mutinga", + "city" => "Barueri", + "state" => "SP" + ]), + "receiver" => new BilletReceiver([ + "document" => "40655847871", + "account" => "30023646056263" + ]), + ]); + } + + public static function successCreateBilletStub(): PromiseInterface + { + return Http::response([ + "version" => "1.0.0", + "status" => "SUCCESS", + "body" => [ + "transactionId" => "ce9b8d9b-0617-42e1-b500-80bf9d8154cf" + ] + ]); + } + + public function testGetBillet() + { + $fake = fake('pt_BR'); + Http::fake( + [ + config('celcoin.login_url') => GlobalStubs::loginResponse(), + sprintf( + '%s%s', + config('api_url'), + CelcoinBAASBillet::CREATE_BILLET_URL . '*', + ) => self::successGetBilletStub(), + ], + ); + + $billet = new CelcoinBAASBillet(); + $result = $billet->getBillet('ce9b8d9b-0617-42e1-b500-80bf9d8154cf'); + + $this->assertEquals('SUCCESS', $result['status']); + $this->assertEquals('ce9b8d9b-0617-42e1-b500-80bf9d8154cf', $result['body']['transactionId']); + + } + + public function successGetBilletStub(): PromiseInterface + { + return Http::response([ + "version" => "1.0.0", + "status" => "SUCCESS", + "body" => [ + "transactionId" => "ce9b8d9b-0617-42e1-b500-80bf9d8154cf", + "externalId" => "externalId1", + "amount" => 12.5, + "amountConfirmed" => 13, + "duedate" => "2023-12-30", + "status" => "CONFIRMED", + "debtor" => [ + "name" => "Marcos Samuel Duarte", + "document" => "49188474801", + "postalCode" => "06463035", + "publicArea" => "Rua Mãe D'Água", + "number" => "1004", + "complement" => "Apto 123", + "neighborhood" => "Jardim Mutinga", + "city" => "Barueri", + "state" => "SP" + ], + "receiver" => [ + "name" => "Emilly Malu Tereza Sales", + "document" => "23234457824", + "postalCode" => "06474070", + "publicArea" => "Alameda França", + "city" => "Barueri", + "state" => "SP", + "account" => "30023646056263" + ], + "instructions" => [ + "fine" => 10, + "interest" => 5, + "discount" => [ + "amount" => 1, + "modality" => "fixed", + "limitDate" => "2023-12-20T00:00:00.0000000" + ] + ], + "boleto" => [ + "transactionId" => "32290", + "status" => "Pago", + "bankEmissor" => "santander", + "bankNumber" => "4000178961", + "bankAgency" => "1004", + "bankAccount" => "0220060", + "barCode" => "03392942700000009009022006000040001789610101", + "bankLine" => "03399022070600004000317896101015294270000000900", + "bankAssignor" => "CELCOIN INSTITUIÇÃO DE PAGAMENTO - SA" + ], + "pix" => [ + "transactionId" => "817885753", + "transactionIdentification" => "817885753", + "status" => "Cancelado", + "key" => "teste@chavepix.com.br", + "emv" => "00020101021226980014br.gov.bcb.pix2576api-h.developer.btgpactual.com/pc/p/v2/cobv/303928a7b4034de09fddec6d1258c15d5204000053039865802BR5910Merle Yost6008Orinside61080863968162070503***6304D7D3" + ], + "split" => [ + [ + "amount" => 5, + "account" => "40655847871" + ] + ] + ] + ]); + } + + /** + * @throws RequestException + */ + public function testFailedCreateBillet() + { + Http::fake( + [ + config('celcoin.login_url') => GlobalStubs::loginResponse(), + sprintf( + '%s%s', + config('api_url'), + CelcoinBAASBillet::CREATE_BILLET_URL . '*', + ) => self::failedBilletStub(), + ], + ); + + $this->expectException(Exception::class); + $billet = new CelcoinBAASBillet(); + $billet->createBillet(self::billetBodyRequest()); + + } + + public static function failedBilletStub(): PromiseInterface + { + return Http::response([ + "version" => "1.0.0", + "status" => "ERROR", + "error" => [ + "errorCode" => "CBE001", + "message" => "Ocorreu um erro interno durante a chamada da api." + ] + ], 401); + } +} From 74f17bc79631be51a22ad8a5dfdf0ddb3f6814f8 Mon Sep 17 00:00:00 2001 From: Michael de Oliveira Ferreira Date: Fri, 6 Oct 2023 02:23:29 -0300 Subject: [PATCH 2/2] feature: create baas billet --- src/Rules/BAAS/Billet.php | 12 ++++++------ tests/Integration/BAAS/CelcoinBASSBilletTest.php | 15 ++++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Rules/BAAS/Billet.php b/src/Rules/BAAS/Billet.php index a5a5719..a2c8b1d 100644 --- a/src/Rules/BAAS/Billet.php +++ b/src/Rules/BAAS/Billet.php @@ -13,7 +13,7 @@ public static function rules(): array 'merchantCategoryCode' => ['sometimes', 'required'], 'expirationAfterPayment' => ['boolean'], 'duedate' => ['required', 'date'], - 'amount' => ['required', 'numeric:0,2'], + 'amount' => ['required', 'decimal:0,2'], 'key' => ['sometimes', 'nullable'], 'debtor' => ['required', 'array'], 'debtor.name' => ['required'], @@ -29,16 +29,16 @@ public static function rules(): array 'receiver.account' => ['required','numeric'], 'instructions' => ['sometimes', 'array'], 'instructions.discounts' => ['required_with:instructions','array'], - 'instructions.discounts.*.amount' => ['nullable','numeric:0,2'], + 'instructions.discounts.*.amount' => ['nullable','decimal:0,2'], 'instructions.discounts.*.modality' => ['nullable'], 'instructions.discounts.*.limitDate' => ['nullable', 'date'], - 'instructions.fine' => ['nullable','numeric:0,2'], - 'instructions.interest' => ['nullable','numeric:0,2'], + 'instructions.fine' => ['nullable','decimal:0,2'], + 'instructions.interest' => ['nullable','decimal:0,2'], 'split' => ['sometimes', 'array'], 'split.*.account' => ['nullable', 'numeric'], 'split.*.document' => ['nullable', 'numeric'], - 'split.*.percent' => ['nullable', 'numeric'], - 'split.*.amount' => ['nullable', 'numeric'], + 'split.*.percent' => ['nullable', 'decimal:0,2'], + 'split.*.amount' => ['nullable', 'decimal:0,2'], 'split.*.aggregatePayment' => ['nullable', 'boolean'], ]; } diff --git a/tests/Integration/BAAS/CelcoinBASSBilletTest.php b/tests/Integration/BAAS/CelcoinBASSBilletTest.php index b350007..533e031 100644 --- a/tests/Integration/BAAS/CelcoinBASSBilletTest.php +++ b/tests/Integration/BAAS/CelcoinBASSBilletTest.php @@ -4,6 +4,7 @@ use Exception; use GuzzleHttp\Promise\PromiseInterface; +use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Http\Client\RequestException; use Illuminate\Support\Facades\Http; use WeDevBr\Celcoin\Clients\CelcoinBAASBillet; @@ -15,7 +16,7 @@ class CelcoinBASSBilletTest extends TestCase { - + use WithFaker; /** * @throws RequestException */ @@ -50,8 +51,8 @@ public static function billetBodyRequest(): Billet "amount" => 12.5, "key" => "testepix@celcoin.com.br", "debtor" => new BilletDebtor([ - "name" => "Marcos Samuel Duarte", - "document" => "49188474801", + "name" => "João teste de teste", + "document" => "12345678910", "postalCode" => "06463035", "publicArea" => "Rua Mãe D'Água", "complement" => null, @@ -61,7 +62,7 @@ public static function billetBodyRequest(): Billet "state" => "SP" ]), "receiver" => new BilletReceiver([ - "document" => "40655847871", + "document" => "12345678910", "account" => "30023646056263" ]), ]); @@ -113,8 +114,8 @@ public function successGetBilletStub(): PromiseInterface "duedate" => "2023-12-30", "status" => "CONFIRMED", "debtor" => [ - "name" => "Marcos Samuel Duarte", - "document" => "49188474801", + "name" => $this->faker->name, + "document" => $this->faker->numerify('###########'), "postalCode" => "06463035", "publicArea" => "Rua Mãe D'Água", "number" => "1004", @@ -125,7 +126,7 @@ public function successGetBilletStub(): PromiseInterface ], "receiver" => [ "name" => "Emilly Malu Tereza Sales", - "document" => "23234457824", + "document" => $this->faker->numerify('###########'), "postalCode" => "06474070", "publicArea" => "Alameda França", "city" => "Barueri",