Skip to content

Commit

Permalink
Merge pull request #4 from TransbankDevelopers/feat/webpay-mall
Browse files Browse the repository at this point in the history
feat: webpay mall
  • Loading branch information
victormendoza96 authored Jul 29, 2024
2 parents a23470c + 3f87b32 commit becaa06
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 19 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# ChatBot para soporte
# Proyecto de Ejemplo SDK PHP

## Descripción

ChatBot de Slack que se conecta con un LLM para apoyar el soporte a las comunidades.
Proyecto de ejemplo mostrando el paso a paso de como usar el SDK PHP de transbank

## Requisitos

- Node 18+
- Slack Bolt
- Dotenv
- PHP 8.3+
- laravel 11

## Iniciar aplicación

Expand Down
26 changes: 14 additions & 12 deletions app/Http/Controllers/WebpayController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __construct()
$this->transaction = new Transaction($option);
}

public function index()
public function create()
{

$createTx = [
Expand All @@ -36,24 +36,26 @@ public function index()
}
public function commit(Request $request)
{
//Timeout
$view = 'webpay.timeout';
$data = ["request" => $request];

//flujo error
if ($request->exists("TBK_TOKEN") && $request->exists("token_ws")) {
return view('webpay.error', ["request" => $request]);
$view = 'webpay.error';
}
//Pago abortadoas
elseif ($request->exists("TBK_TOKEN")) {
$view = 'webpay.error';
}

//Flujo normal
if ($request->exists("token_ws")) {
elseif ($request->exists("token_ws")) {
$resp = $this->transaction->commit($request["token_ws"]);
return view('webpay.commit', ["resp" => $resp, "token" => $request["token_ws"]]);
$view = 'webpay.commit';
$data = ["resp" => $resp, "token" => $request["token_ws"]];
}

//Pago abortadoas
if ($request->exists("TBK_TOKEN")) {
return view('webpay.error', ["request" => $request]);
}

//Timeout
return view('webpay.timeout', ["request" => $request]);
return view($view, $data);
}

public function refund(Request $request)
Expand Down
94 changes: 94 additions & 0 deletions app/Http/Controllers/WebpayPlusMallController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Transbank\Webpay\Options;
use Transbank\Webpay\WebpayPlus\MallTransaction;

class WebpayPlusMallController extends Controller
{
const COMMERCE_CODE = "597055555535";
const API_KEY = "579B532A7440BB0C9079DED94D31EA1615BACEB56610332264630D42D0A36B1C";
private MallTransaction $mallTransaction;
public function __construct()
{
$option = new Options(self::API_KEY, self::COMMERCE_CODE, Options::ENVIRONMENT_INTEGRATION);
$this->mallTransaction = new mallTransaction($option);
}

public function create()
{

$createTx = [
'buy_order' => "O-" . rand(1, 10000),
"session_id" => "S-" . (string)(rand(1, 10000)),
'return_url' => url('/') . '/webpay-mall/commit',
];
$details = [
[
"amount" => 10000,
"commerce_code" => 597055555536,
"buy_order" => "ordenCompraDetalle1234"
],
[
"amount" => 12000,
"commerce_code" => 597055555537,
"buy_order" => "ordenCompraDetalle4321"
],
];

$resp = $this->mallTransaction->create($createTx["buy_order"], $createTx["session_id"], $createTx["return_url"], $details);

return view('webpay-mall.create', ["request" => $createTx, "resp" => $resp]);
}



public function commit(Request $request)
{
//Timeout
$view = 'webpay-mall.timeout';
$data = ["request" => $request];

//flujo error
if ($request->exists("TBK_TOKEN") && $request->exists("token_ws")) {
$view = 'webpay-mall.error';
}
//Pago abortadoas
elseif ($request->exists("TBK_TOKEN")) {
$view = 'webpay-mall.error';
}
//Flujo normal
elseif ($request->exists("token_ws")) {
$resp = $this->mallTransaction->commit($request["token_ws"]);
$view = 'webpay-mall.commit';
$data = ["resp" => $resp, "token" => $request["token_ws"]];
}

return view($view, $data);
}


public function status(Request $request)
{
$req = $request->except('_token');
$resp = $this->mallTransaction->status($req["token"]);
return view('webpay-mall.status', ["resp" => $resp, "req" => $req]);
}

public function refund(Request $request)
{
try {
$req = $request->except('_token');
$resp = $this->mallTransaction->refund($req["token"], $req["buyOrder"], $req["childComerceCode"], $req["amount"]);
} catch (\Exception $e) {
$resp = array(
'msg' => $e->getMessage(),
'code' => $e->getCode()
);
return view('webpay-mall.refund', ["resp" => $resp, "req" => $req]);
}
return view('webpay-mall.refund', ["resp" => $resp, "req" => $req]);
}
}
5 changes: 5 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ code {
margin-bottom: 32px;
}

.tbk-link {
color: var(--tbk-red);
text-decoration: underline;
}

/* layout */

.main-container {
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 @@ -4,7 +4,7 @@
@foreach ([
'Wepbay Plus' => route('webpay.create'),
'Wepbay Plus Diferido' => route('webpay.create'),
'Wepbay Mall' => route('webpay.create'),
'Wepbay Mall' => route('webpay-mall.create'),
'Wepbay Mall Diferido' => route('webpay.create'),
] as $menuItemName => $url)
<a href="{{ $url }}" class="tbk-menu-item {{ $activeLink == $menuItemName ? 'active' : '' }}">
Expand Down
79 changes: 79 additions & 0 deletions resources/views/webpay-mall/commit.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@php
$navigation = ['confirm' => 'Confirmar transacción', 'other' => 'Otras operaciones'];
@endphp

<x-layout active-link="Wepbay Mall" :navigation="$navigation">

<h1 id="confirm">Webpay Mall - Confirmar transacción</h1>
<p class="mb-32">En este paso es importante confirmar la transacción para notificar a Transbank que hemos recibido
exitosamente los detalles de la transacción. Es importante destacar que si la confirmación no se realiza, la
transacción será reversada.
</p>

<h2>Paso 1 - Datos recibidos:</h2>
<ul class="mb-32">
<p class="m-32">
Después de completar el flujo en el formulario de pago, recibirás un GET con la siguiente
información:
</p>
</ul>
<x-snippet>(returnUrl)?token_ws={{ $token }} </x-snippet>

<h2>Paso 2 - Petición:</h2>
<p class="mb-32">
Utilizarás el token recibido para confirmar la transacción mediante el SDK.
</p>

<x-snippet>
$resp = $transaction->commit($token);
</x-snippet>

<h2>Paso 3 - Respuesta:</h2>
<p class="mb-32">
Transbank responderá con la siguiente información. Es crucial guardar esta respuesta, y la única
validación necesaria es que el campo "response_code" sea igual a cero.
</p>

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


<h2>¡Listo!</h2>
<p class="mb-32">
Con la confirmación exitosa, ya puedes mostrar al usuario una página de éxito de la transacción,
proporcionándole la tranquilidad de que el proceso ha sido completado con éxito.
</p>
<p>
Después de confirmar la transacción, podrás realizar otras operaciones útiles:
</p>
<ul id="other">
<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('webpay-mall.refund') }} method="POST">
@csrf
<div class="tbk-card">
<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 }}>
<input type="hidden" name="childComerceCode" class="tbk-input-text"
value={{ $detail->commerceCode }}>
<input type="hidden" name="buyOrder" class="tbk-input-text" value={{ $detail->buyOrder }}>
<input type="hidden" name="token" class="tbk-input-text" value={{ $token }}>
</div>
<div class="tbk-card-footer ">
<button class="tbk-button primary">REEMBOLSAR</button>
</div>
</div>
</form>
@endforeach
<a href={{ route('webpay-mall.status', ['token' => $token]) }} class="tbk-button primary mb-32">CONSULTAR ESTADO</a>
</x-layout>
87 changes: 87 additions & 0 deletions resources/views/webpay-mall/create.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
@php
$navigation = ['create' => 'Crear transacción', 'example' => 'Ejemplo'];
@endphp

<x-layout active-link="Wepbay Mall" :navigation="$navigation">
<h1 id="create">Webpay Mall - Creación de transacción Mall
</h1>
<p class="mb-32">
En esta etapa, se procederá a la creación de una transacción con el fin de obtener un identificador
único. Esto nos permitirá redirigir al Tarjetahabiente hacia el formulario de pago en el siguiente paso.

</p>

<h2>Paso 1: Petición</h2>
<ul class="mb-32">
<li>Comienza por importar la librería WebpayPlus en tu proyecto.</li>
<li>Luego, crea una transacción utilizando las funciones proporcionadas mediante el SDK.</li>
</ul>
<pre class="mb-32"><code>
use Transbank\Webpay\Options;
use Transbank\Webpay\WebpayPlus\MallTransaction;
//configuración de la transacción
$details = [
[
"amount" => 10000,
"commerce_code" => 597055555536,
"buy_order" => "ordenCompraDetalle1234"
],
[
"amount" => 12000,
"commerce_code" => 597055555537,
"buy_order" => "ordenCompraDetalle4321"
],
];
$option = new Options(API_KEY, COMMERCE_CODE, Options::ENVIRONMENT_INTEGRATION);
$mallTransaction = new mallTransaction($option);
$resp = $mallTransaction->create($buy_order, $session_id, $return_url,
$details);
</code></pre>


<h2>Paso 2: Respuesta</h2>
<p class="mb-32">Una vez que hayas creado la transacción, aquí encontrarás los datos de respuesta generados por el
proceso.
</p>

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

<h2>Paso 3: Creación del formulario</h2>
<p class="mb-32">Utiliza estos datos de respuesta para generar y presentar un formulario de pago al Tarjetahabiente.
Este formulario será la interfaz a través de la cual el usuario realizará su transacción.
</p>

<x-snippet>
form action="https://webpay3gint.transbank.cl/webpayserver/initTransaction" method="POST">
input type="hidden" name="token_ws" value="{{ $resp->token }}" />
input type="submit" value="Pagar" />
form>
</x-snippet>

<h2 id="example">Ejemplo</h2>
<p class="mb-32">Para llevar a cabo una transacción de compra en nuestro sistema, primero debemos crear la
transacción. Utilizaremos los siguientes datos para configurar la transacción:
</p>

<div class="mb-32">
<x-table :request="$request" />
</div>

<p class="mb-32">Por último, con la respuesta del servicio que confirma la creación de la transacción, procedemos
a crear el formulario de pago. Para fines de este ejemplo, haremos visible el campo "token_ws", el cual es
esencial para completar el proceso de pago de manera exitosa.
</p>

<form action={{ $resp->url }} action="POST">
<div class="tbk-card">
<span class="tbk-card-title">Formulario de redirección</span>
<div class="input-container">
<label for="tokew_ws" class="tbk-label">Token</label>
<input type="text" name="token_ws" class="tbk-input-text" value={{ $resp->token }} required>
</div>
<div class="tbk-card-footer">
<button class="tbk-button primary">PAGAR</button>
</div>
</div>
</form>
</x-layout>
46 changes: 46 additions & 0 deletions resources/views/webpay-mall/refund.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@php
$navigation = ['refund' => 'Reembolsar'];
@endphp

<x-layout active-link="Wepbay Mall" :navigation="$navigation">
<h1 id="refund">Webpay Plus - Reembolsar</h1>
<p class="mb-32">En esta etapa, tienes la opción de solicitar el reembolso del monto al titular de la tarjeta.
Dependiendo del monto y el tiempo transcurrido desde la transacción, este proceso podría resultar en una
Reversa, Anulación o Anulación Parcial.

</p>

<h2>Paso 1 - Petición:</h2>
<p class="mb-32">
Para llevar a cabo el reembolso, necesitas proporcionar el token de la transacción, el monto que
quieres reversar, el código de comercio de la tienda hijo y el orden de compra del detalle de la transacción. Si
anulas el monto total, podría ser una Reversa o Anulación, dependiendo de ciertas condiciones, o una Anulación
Parcial si el monto es menor al total.
</p>

<p>Algunas consideraciones a tener en cuenta</p>
<ul class="mb-32">
<li>
No es posible realizar Anulaciones ni Anulaciones Parciales en tarjetas que no sean de crédito.
</li>
<li>
No es posible realizar Anulaciones Parciales en pagos con cuotas.
</li>
<li>No se admiten reembolsos de compras en cuotas.</li>
</ul>

<p>En <a href="https://www.transbankdevelopers.cl/producto/webpay#anulaciones-y-reversas" class="tbk-link">este link
</a> podrás ver
mayor información sobre las condiciones y casos para anular o reversar transacciones.</p>
<x-snippet>
$resp = $mallTransaction->refund($token, $buyOrder, $childComerceCode,
$amount);
</x-snippet>

<h2>Paso 2: Respuesta</h2>
<p class="mb-32">Transbank responderá con el resultado del proceso de reembolso, indicando si se ha realizado una
Reversa, Anulación o Anulación Parcial.
</p>

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

0 comments on commit becaa06

Please sign in to comment.