alexmart/laravel-flow

Laravel 6 包用于与 Flow (https://www.flow.cl) 集成支付

dev-master 2020-01-12 03:04 UTC

This package is not auto-updated.

Last update: 2024-09-30 11:58:29 UTC


README

Laravel 6 包用于与 Flow 集成支付

已测试与 Laravel 6 兼容

尊敬的开发者,本包是为了使用 FLOW 的新 API 重写的,这是因为旧包已过时且在新版本的 Laravel 上无法使用。

安装

步骤 1:通过 Composer 安装

$ composer require alexmart/laravel-flow

步骤 2:添加 Service Provider [仅适用于 Laravel < 5.5]

在文件 config/app.php 中,将以下行添加到 providers 数组中

'providers' => [
    AlexMart\LaravelFlow\FlowServiceProvider::class,
],

步骤 3:添加别名 [仅适用于 Laravel < 5.5]

在同一个文件中,将以下行添加到 aliases 数组中

'aliases' => [
    …
    'Flow' => AlexMart\LaravelFlow\Facades\Flow::class,
    …
],

步骤 4:发布配置文件

$ php artisan vendor:publish --provider="AlexMart\LaravelFlow\FlowServiceProvider" --force

步骤 5:配置你的 .env 或修改 config/flow.php

…
FLOW_URL_PAGO=https://sandbox.flow.cl/app/web/pay.php
FLOW_COMERCIO=emailFlow@comercio.com
FLOW_API_KEY=Tu_api_key_aqui
FLOW_SECRET_KEY=Tu_api_secreta_aqui

使用方法

此包基本上作为一个简单的 Service Provider 为 Flow 集成套件 服务,因此我将仅举例说明其在 Laravel 中的使用差异。

重要: 排除成功、失败和确认页面的 CSRF 保护,因为 Flow 不会知道应向你的路由发送什么 CSRF 令牌。

演示项目

注意:本包的演示项目尚未提供...

在查看以下示例之前,你可能想先查看 演示项目,该项目在 Laravel 6 中实现了本包,或者一起分析以更好地理解如何使用它。

购买表单

视图:resources/views/index.blade.php

@extends('layouts._master')

@section('content')
    <form method="POST" action="{{ route('orden') }}">
        @csrf
        Orden N°: <input type="text" name="orden" id="orden" placeholder="1000" required><br>
        Monto: <input type="text" name="monto" id="monto" placeholder="20000" required><br>
        Descripción: <input type="text" name="concepto" id="concepto" placeholder="Pago de Orden N° 1000" required><br>
        Email pagador (opcional): <input type="email" name="pagador" id="pagador" placeholder="usuario@email.com"><br>
        <br>
        <button type="submit">Aceptar</button>
    </form>
@endsection

创建新订单

控制器:Http/Controllers/FlowController.php[示例]

<?php

namespace App\Http\Controllers;

use Flow;

use Illuminate\Http\Request;

class FlowController extends Controller
{
    /**
     * Creando una nueva Orden
     *
     * @param Request $request
     * @return \Illuminate\View\View
     */
    public function orden(Request $request)
    {
        $orden = [
            //SEGUIR EL ORDEN Y NOMBRE DE CLAVES COMO SE MUESTRA A CONTINUACION
            'commerceOrder'  => $request->orden,
            'subject'      => $request->concepto,
            'amount'         => $request->monto,
            'email' => $request->pagador,

            // Opcional: El medio de pago correspondera al ubicado en la configuracion
        ];

        // Genera una nueva Orden de Pago, Flow la firma y retorna un paquete de datos firmados
        $orden_generada = Flow::GenerateFlowOrder($orden);

        // Si desea enviar el medio de pago usar la siguiente línea
        //$orden['flow_pack'] = Flow::new_order($orden['orden_compra'], $orden['monto'], $orden['concepto'], $orden['email_pagador'], $orden['medio_pago']);

        return view('orden')->with(['order'=>$generated_order]);
    }
…

视图:resources/views/orden.blade.php

@extends('layouts._master')

@section('content')
    <!-- Formulario HTML que envía la nueva Orden -->
    Confirme su orden antes de proceder al pago via Flow<br>
    <br>
    Orden N°: {{ $order['commerceOrder'] }}<br>
    Orden FLOW N°: {{ $order['response']->flowOrder }}<br>
    Monto: {{ $order['amount'] }}<br>
    Descripción: {{ $order['subject'] }}<br>
    Email pagador (opcional): {{ $order['email'] }}<br>
    <br>
    <form method="POST" action="{{ config('flow.url_pago') }}">
        @csrf
        <input type="hidden" name="token" value="{{ $order['response']->token }}">
        <button type="submit">Pagar en Flow</button>
    </form>
@endsection

成功页面

控制器:Http/Controllers/FlowController.php

…
    /**
     * Página de éxito del Comercio
     *
     * Esta página será invocada por Flow cuando la transacción resulte exitosa
     * y el usuario presione el botón para retornar al comercio desde Flow.
     *
     * @return \Illuminate\View\View
     */
    public function exito(Request $request)
    {
        // Lee los datos enviados por Flow
        $GetFlowOrder = \Flow::getStatus($request->token);

        // Recupera los datos enviados por Flow
        // Lista completa del retorno de datos: https://www.flow.cl/docs/api.html#tag/payment/paths/~1payment~1getStatus/get
        $orden = [
            'flowOrder'     => $GetFlowOrder->flowOrder,
            'commerceOrder' => $GetFlowOrder->commerceOrder,
            'subject'       => $GetFlowOrder->subject,
            'payer'         => $GetFlowOrder->payer,
        ];

        return view('flow.exito')->with(["FlowOrder" => $orden]);
    }
…

视图:resources/views/flow/exito.blade.php

@extends('layouts._master')

@section('content')
    <h1>Página de éxito de Comercio</h1>
    Su pago se ha realizado exitosamente<br>
    <br>
    Orden de Compra: {{ $FlowOrder['flowOrder'] }}<br>
    <br>
    Gracias por su compra
@endsection

失败页面 [未实现]

控制器:Http/Controllers/FlowController.php

…
    /**
     * Página de fracaso del Comercio
     *
     * Esta página será invocada por Flow cuando la transacción no se logre pagar
     * y el usuario presione el botón para retornar al comercio desde Flow.
     *
     * @return \Illuminate\View\View
     */
    public function fracaso()
    {
        // Lee los datos enviados por Flow
        Flow::read_result();

        // Recupera los datos enviados por Flow
        $orden = [
            'orden_compra'  => Flow::getOrderNumber(),
            'monto'         => Flow::getAmount(),
            'concepto'      => Flow::getConcept(),
            'email_pagador' => Flow::getPayer(),
            'flow_orden'    => Flow::getFlowNumber(),
        ];

        return view('flow.fracaso', $orden);
    }
…

视图:resources/views/flow/fracaso.blade.php

@extends('layouts._master')

@section('content')
    <h1>Página de fracaso de Comercio</h1>
    Su pago ha sido rechazado<br>
    <br>
    Orden de Compra: {{ $orden_compra }}<br>
    Monto: {{ $monto }}<br>
    Descripción: {{ $concepto }}<br>
    Pagador: {{ $email_pagador }}<br>
    Flow Orden N°: {{ $flow_orden }}<br>
    <br>
    <a href="{{ url('/') }}">Intente nuevamente</a>
@endsection

确认页面

控制器:Http/Controllers/FlowController.php

…
    /**
     * Página de confirmación del Comercio
     *
     * @return void
     */
    public function confirmacion()
    {
        try {
            // Lee los datos enviados por Flow
            Flow::read_confirm();
        } catch (Exception $e) {
            // Si hay un error responde false
            echo Flow::build_response(false);
            return;
        }

        // Recupera los valores de la Orden
        $flow_status  = Flow::getStatus();      // El resultado de la transacción (EXITO o FRACASO)
        $orden_numero = Flow::getOrderNumber(); // N° de Orden del Comercio
        $monto        = Flow::getAmount();      // Monto de la transacción
        $orden_flow   = Flow::getFlowNumber();  // Si $flow_status = 'EXITO' el N° de Orden de Flow
        $pagador      = Flow::getPayer();       // El email del pagador

        /**
         * Aquí puede validar la Orden
         *
         * Si acepta la Orden responder Flow::build_response(true)
         * Si rechaza la Orden responder Flow::build_response(false)
         */
        if ($flow_status == 'EXITO') {
            // La transacción fue aceptada por Flow
            // Aquí puede actualizar su información con los datos recibidos por Flow
            echo Flow::build_response(true); // Comercio acepta la transacción
        } else {
            // La transacción fue rechazada por Flow
            // Aquí puede actualizar su información con los datos recibidos por Flow
            echo Flow::build_response(false); // Comercio rechaza la transacción
        }
    }
…

路由

…
Route::get('/', function () {
    return view('index');
});
Route::post('orden', 'FlowController@orden')->name('orden');

Route::post('flow/exito', 'FlowController@exito')->name('flow.exito');
Route::post('flow/fracaso', 'FlowController@fracaso')->name('flow.fracaso');
Route::post('flow/confirmacion', 'FlowController@confirmacion')->name('flow.confirmacion');
…