Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add oneclick path to proyect #9

Merged
merged 28 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
784d28b
feat: create error page
victormendoza96 Aug 22, 2024
7d04803
feat: create delete page for oneclick
victormendoza96 Aug 22, 2024
17aa158
feat: create oneclikmallcontroller
victormendoza96 Aug 22, 2024
3d72d41
feat: add css for multile line fields in card
victormendoza96 Aug 22, 2024
f6b550a
refactor: use correct url dor oneclick mall
victormendoza96 Aug 22, 2024
4c56233
refactor: use correct url for oneclick in menu
victormendoza96 Aug 22, 2024
caea63f
feat: create authorize page for oneclick mall
victormendoza96 Aug 22, 2024
49a3c46
feat: create finish page for oneclick mall
victormendoza96 Aug 22, 2024
d1c2c56
feat: create refund page for oneclick mall
victormendoza96 Aug 22, 2024
c107376
feat: create error rejected page for oneclick mall
victormendoza96 Aug 22, 2024
491dc33
feat: create start inscription page for oneclick mall
victormendoza96 Aug 22, 2024
9965507
feat: create status page for oneclick mall
victormendoza96 Aug 22, 2024
9979f99
feat: create timeout page for oneclick mall
victormendoza96 Aug 22, 2024
08910ab
feat: add protection for window.opener
victormendoza96 Aug 22, 2024
22ee5d4
fix: use correct tag
victormendoza96 Aug 22, 2024
15b372b
feat: create routes for oneclick mall
victormendoza96 Aug 22, 2024
8b573ce
fix: typo
victormendoza96 Aug 26, 2024
83cf6d1
feat: add more info about refund
victormendoza96 Aug 26, 2024
76adb12
refactor: resume content
victormendoza96 Aug 26, 2024
89601e8
fix: magic numbers
victormendoza96 Aug 26, 2024
758f076
fix : typo
victormendoza96 Aug 26, 2024
4df6b80
fix: multiple return
victormendoza96 Aug 26, 2024
f63d752
fix: typo
victormendoza96 Aug 26, 2024
c7e91b4
feat: add recorevytransaction page
victormendoza96 Aug 26, 2024
86399f8
refactor: use elseif
victormendoza96 Aug 28, 2024
0783d12
feat: add link to github issue
victormendoza96 Aug 28, 2024
f04bf57
feat: add more info for timeout in integration
victormendoza96 Aug 28, 2024
978905a
fix: remove route
victormendoza96 Aug 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions app/Http/Controllers/OneclickMallController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Transbank\Webpay\Options;
use Transbank\Webpay\Oneclick\MallInscription;
use Transbank\Webpay\Oneclick\MallTransaction;

class OneclickMallController extends Controller
{

const TIMEOUT = -96;
const REJECTED = -1;
const COMMERCE_CODE = "597055555541";
const API_KEY = "579B532A7440BB0C9079DED94D31EA1615BACEB56610332264630D42D0A36B1C";
private MallInscription $mallInscription;
private MallTransaction $mallTransaction;

public function __construct()
{
$option = new Options(self::API_KEY, self::COMMERCE_CODE, Options::ENVIRONMENT_INTEGRATION);
$this->mallInscription = new MallInscription($option);
$this->mallTransaction = new MallTransaction($option);
}

public function startInscription()
{
try {

$startTx = [
"username" => "User-" . random_int(1, 10000),
"email" => "user." . random_int(1, 10000) . "@example.cl",
"response_url" => url("/") . "/oneclick-mall/finish"
];

session(['username' => $startTx["username"]]);
$resp = $this->mallInscription->start($startTx["username"], $startTx["email"], $startTx["response_url"]);
return view('oneclick-mall.start', ["request" => $startTx, "resp" => $resp]);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}

public function finishInscription(Request $request)
{
try {
$view = 'error-page';
$data = ["error" => $request];
$params = $request->only(['TBK_ORDEN_COMPRA', 'TBK_TOKEN', 'TBK_ID_SESION']);
$token = $request["TBK_TOKEN"];
$userName = session('username', '');

if ($request->exists("TBK_ORDEN_COMPRA")) {
return view('oneclick-mall.recoverTransaction', ["req" => $params]);
}

$resp = $this->mallInscription->finish($token);

if ($resp->responseCode == self::REJECTED) {
$view = 'oneclick-mall.rejected';
$data = ["resp" => $resp, "token" => $token];
} elseif ($resp->responseCode == self::TIMEOUT) {
$view = 'oneclick-mall.timeout';
$data = ["resp" => $resp];
} else {
$table = [
"username" => $userName,
"tbk_user" => $resp->tbkUser,
];
$data = ["resp" => $resp, "token" => $token, "table" => $table];
$view = 'oneclick-mall.finish';
}

return view($view, $data);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}
public function deleteInscription(Request $request)
{
try {
$tbkUser = $request["tbkUser"];
$userName = $request["userName"];
$resp = $this->mallInscription->delete($tbkUser, $userName);
return view('oneclick-mall.delete', ["resp" => $resp]);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}

public function authorizeMall(Request $request)
{
try {
$tbkUser = $request["tbkUser"];
$userName = $request["userName"];
$buyOrder = "O-" . random_int(1000, 9999);
$details = [
[
"commerce_code" => "597055555542",
"buy_order" => "O1-" . random_int(1000, 9999),
"amount" => 1693,
"installments_number" => 1
],
[
"commerce_code" => "597055555543",
"buy_order" => "O2-" . random_int(1000, 9999),
"amount" => 1960,
"installments_number" => 1
]
];

$resp = $this->mallTransaction->authorize($userName, $tbkUser, $buyOrder, $details);
return view('oneclick-mall.authorize', ["resp" => $resp]);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}

public function status(Request $request)
{
try {
$buyOrder = $request["buyOrder"];
$resp = $this->mallTransaction->status($buyOrder);
return view('oneclick-mall.status', ["resp" => $resp]);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}

public function refund(Request $request)
{
try {
$req = $request->except('_token');
$buyOrder = $req["buyOrder"];
$childCommerceCode = $req["childCommerceCode"];
$childBuyOrder = $req["childBuyOrder"];
$amount = $req["amount"];

$resp = $this->mallTransaction->refund($buyOrder, $childCommerceCode, $childBuyOrder, $amount);

return view('oneclick-mall.refund', ["resp" => $resp]);
} catch (\Exception $e) {
$error = ["msg" => $e->getMessage(), "code" => $e->getCode()];
return view('error-page', ["error" => $error]);
}
}
}
32 changes: 32 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ code {
.mb-32 {
margin-bottom: 32px;
}
.mb-16 {
margin-bottom: 16px;
}

.tbk-link {
color: var(--tbk-red);
Expand Down Expand Up @@ -658,12 +661,17 @@ code {
line-height: 24px;
letter-spacing: 0.25px;
}
/* Error page */

.layout-error {
margin: 80px 156px;
}
/* homepage */

.layout-home {
display: grid;
grid-template-rows: auto 1fr auto;
height: 100vh;
}

.tbk-home-container {
Expand Down Expand Up @@ -757,6 +765,24 @@ code {
background-color: var(--tbk-grey-4);
}
}
.card-multi-field {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 32px;
}

.divided-card {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}

.card-right-container {
display: flex;
flex-direction: column;
align-items: end;
gap: 16px;
}

@media (max-width: 1439.98px) {
.body-container {
Expand All @@ -767,6 +793,12 @@ code {
}
}

@media (max-width: 1023.98px) {
.card-multi-field {
grid-template-columns: 1fr;
}
}

@media (max-width: 576px) {
.tbk-table {
display: none;
Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/menu.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class="tbk-menu-item-container">
<span class="tbk-menu-item-text">Webpay Oneclick</span>
@foreach ([
'Oneclick Mall' => route('webpay.create'),
'Oneclick Mall' => route('oneclick-mall.start'),
'Oneclick Mall Diferido' => route('webpay.create'),
] as $menuItemName => $url)
<a href="{{ $url }}" class="tbk-menu-item {{ $activeLink == $menuItemName ? 'active' : '' }}">
Expand Down
39 changes: 39 additions & 0 deletions resources/views/error-page.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en" data-theme="light" class="light">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transbank Developers</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body>
<div class="layout-home">
@include('partials.header')

<main class="layout-error">

<h1>¡Ha ocurrido un error!</h1>

<p class="mb-16">
Lo sentimos, pero se ha producido un error durante la integración con el SDK. El SDK
devuelve una Exception.
</p>
<x-snippet :content="$error" />
<p class="mb-32">Si este error persiste y crees que es necesario reportarlo, por favor, hazlo en nuestro
repositorio de <a class="tbk-link" target="_blank" rel="noopener"
href="https://github.com/TransbankDevelopers/transbank-sdk-php-example/issues/new">GitHub.
</a>
</p>



<a href="{{ route('home') }}" class="tbk-button primary mb-32">Volver</a>
</main>
@include('partials.footer')
</div>
@stack('scripts')
</body>

</html>
2 changes: 1 addition & 1 deletion resources/views/home.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class="card-info-image" />
para el tarjetahabiente, una vez que este haya registrado su tarjeta en el comercio.
</p>
</div>
<a href={{ route('oneclick-mall') }} class="card-info-link">
<a href={{ route('oneclick-mall.start') }} class="card-info-link">
Ver ejemplos y modalidades
</a>
</div>
Expand Down
98 changes: 98 additions & 0 deletions resources/views/oneclick-mall/authorize.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
@php
$navigation = ['auth' => 'Autorizar pago', 'other' => 'Consultas'];
@endphp

<x-layout active-link="Oneclick Mall" :navigation="$navigation">
<h1 id="auth">Oneclick Mall - Autorizar pago</h1>
<p class="mb-32">
En este primer paso, procederemos a autorizar una transacción en la tarjeta que ha sido previamente inscrita.
</p>

<h2>Paso 1: Peticion</h2>
<p class="mb-32">
Ahora que contamos con el "username" y el "tbk_user" obtenidos durante la inscripción, estamos listos para
autorizar transacciones en la tarjeta inscrita.
</p>
<x-snippet>
$details = [
-[
---"child_commerce_code",
---"child_buy_order",
---"amount",
---"installments_number"
-],
-[
---"child_commerce_code2",
---"child_buy_order2",
---"amount",
---"installments_number",
-]
];

$resp = $mallTransaction->authorize($userName, $tbkUser, $buyOrder, $details);
</x-snippet>

<h2>Paso 2: Respuesta</h2>
<p class="mb-32">
Una vez que la transacción ha sido autorizada, recibirás los siguientes datos de respuesta:
</p>

<x-snippet :content="$resp" />

<h2>¡Listo!</h2>
<p class="mb-32">
Con la autorización exitosa, puedes mostrar al usuario una página de éxito de la transacción, proporcionándole
la confirmación de que el proceso se ha completado con éxito.
</p>

<h2 id="other">Otras utilidades</h2>
<p class="mb-32">Con la inscripción exitosa se pueden autorizar transacciones.</p>

<h2>Autorizar una transacción</h2>
<p class="mb-32">
Después de autorizar la transacción, considera las siguientes utilidades adicionales:
</p>
<ul>
<li>
<span class="fw-700">Reembolsar:</span> Puedes reversar o anular el pago según ciertas condiciones
comerciales.
</li>
<li>
<span class="fw-700">Consultar Estado:</span> Hasta 7 días después de la transacción, podrás consultar el
estado de la transacción.
</li>
</ul>

@foreach ($resp->details as $detail)
<form action={{ route('oneclick-mall.refund') }} method="POST">
@csrf
<div class="tbk-card">
<div class="card-multi-field">
<div class="input-container">
<label for="buyOrder" class="tbk-label">Orden compra:</label>
<input type="text" name="buyOrder" class="tbk-input-text" value={{ $resp->buyOrder }}>
</div>
<div class="input-container">
<label for="childCommerceCode" class="tbk-label">Código de comercio:</label>
<input type="text" name="childCommerceCode" class="tbk-input-text"
value={{ $detail->commerceCode }}>
</div>
<div class="input-container">
<label for="childBuyOrder" class="tbk-label">Orden de compra (tienda hija):</label>
<input type="text" name="childBuyOrder" class="tbk-input-text" value={{ $detail->buyOrder }}>
</div>
<div class="input-container">
<label for="amount" class="tbk-label">Monto a reembolsar:</label>
<input type="text" name="amount" class="tbk-input-text" value={{ $detail->amount }}>
</div>
</div>
<div class="tbk-card-footer ">
<button class="tbk-button primary">REEMBOLSAR</button>
victormendoza96 marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</form>
@endforeach
<a href={{ route('oneclick-mall.status', ['buyOrder' => $resp->buyOrder]) }}
class="tbk-button primary mb-32">CONSULTAR ESTADO</a>

</x-layout>
Loading