freshwork/transbank

Transbank webservices 的 SDK(Webpay Plus、Webpay OneClick、Webpay PatPass)

1.2.2 2021-10-29 20:28 UTC

README

此 SDK 已无意义,因为 Transbank 已发布新的 API REST,而此 SDK 使用的是旧的方法。Transbank 已不接受 SOAP 集成,幸运的是,我现在负责 TBK 的官方 SDK,因此我建议您现在使用该 SDK:https://github.com/TransbankDevelopers/transbank-sdk-php

所有文档可在 transbankdevelopers.cl 找到

Transbank WebServices SDK

用于集成 Webpay Plus、Webpay OneClick 和 Webpay Patpass 的库。此库由 freshworkstudio.com 的 Gonzalo De Spirito 和 simplepay.cl 维护。还包括 Laravel 的集成。

英文版本:[English](https://github.com/freshworkstudio/transbank-web-services/blob/HEAD/README.en.md)

Freshwork Studio's Transbank SDK
Software License

新功能

  • 在版本 1.2.0 中,包括 Laravel 的集成
  • 创建了一个 证书生成器,它使用官方指令,无需在您的机器上运行命令。

需要帮助

  • 此 SDK 不支持 Webpay REST API。由于时间有限,我未能实现,但如果您愿意帮助,请留下问题,或者以其他方式联系我:)。我很乐意接受支持。

目录

安装

composer require freshwork/transbank  

快速入门

视频教程 | 实现Webpay Plus正常

image
观看屏幕截图

Webpay OneClick和Webpay Plus的示例商店

使用Webpay OneClick和Webpay Plus开发的测试商店。

https://github.com/freshworkstudio/demo-store

示例

example 文件夹中找到了一些示例。我们将随着时间的推移不断增加更多示例。要运行示例

git clone git@github.com:freshworkstudio/transbank-web-services.git
cd transbank-web-services/
php -S localhost:8888 -t examples

现在只需打开您的网络浏览器至 https://:8888/

实现不同服务

Transbank 提供了多种产品,以在商店和其他应用程序中实现支付。
在此文档中,您可以找到有关以下内容的详细信息

  • 具有授权和同步捕获的 Webpay Plus Webservices(正常)
  • 具有授权和延迟捕获的 Webpay Plus Webservices
  • Webpay OneClick
  • PatPass

凭证

集成环境的凭证(证书)已包含在本库中,以简化其实现。它不断通过维护此信息的官方仓库进行更新:https://github.com/TransbankDevelopers/transbank-webpay-credenciales

Webpay Plus正常

使用Webpay的正常交易。(信用卡和借记卡支付)

交易开始

要开始支付流程,您必须通知Transbank您的客户将支付多少和什么,以及将用于验证支付是否成功的中途返回URL,以及将用于显示支付和订单详情的最终URL。

在通知Transbank此交易后,它将向您提供一个TOKEN和一个URL。您必须使用这些数据通过HTTP POST请求(必须通过POST)将用户重定向到该URL(Webpay),您可以通过HTML表单来完成此操作。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
use Freshwork\Transbank\RedirectorHelper;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay Normal.  
$bag = CertificationBagFactory::integrationWebpayNormal();  
  
$plus = TransbankServiceFactory::normal($bag);  
  
// Para transacciones normales, solo puedes añadir una linea de detalle de transacción.  
$plus->addTransactionDetail(10000, 'Orden824201'); // Monto e identificador de la orden  
  
// Debes además, registrar las URLs a las cuales volverá el cliente durante y después del flujo de Webpay  
$response = $plus->initTransaction('http://test.dev/response', 'http://test.dev/thanks');  
  
// Utilidad para generar formulario y realizar redirección POST  
echo RedirectorHelper::redirectHTML($response->url, $response->token);  

返回中间 URL

用户支付后,Webpay将暂时将客户重定向到您的页面,以便您可以验证交易。
为此,它将在一个HTTP POST请求的主体中发送一个TOKEN,键为token_ws$_POST['token_ws']),但是您不必担心这一点,因为getTransactionResult方法会内部捕获此值。

执行此方法(getTransactionResult)时,我们将请求Transbank有关支付及其状态的信息。我们必须检查这一点,并验证订单之前尚未支付。

如果一切顺利,您必须使用acknowledgeTransaction通知Transbank您已验证交易(否则将撤销支付),然后以相同的方式将客户重新重定向到Webpay,以便他们可以接收他们的收据。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
use Freshwork\Transbank\RedirectorHelper;  
  
include 'vendor/autoload.php';  
  
$bag = CertificationBagFactory::integrationWebpayNormal();  
  
$plus = TransbankServiceFactory::normal($bag);  
  
$response = $plus->getTransactionResult();  
  
// Comprueba que el pago se haya efectuado correctamente  
if (  
    $response->detailOutput->responseCode == 0
    /* Comprueba que la orden no haya sido pagada */  
) {  
    $plus->acknowledgeTransaction();  
}  
  
// Redirecciona al cliente a Webpay para recibir el Voucher  
return RedirectorHelper::redirectBackNormal($response->urlRedirection);  

返回最终 URL

在这个页面上,您必须显示在调用getTransactionResult步骤中获得的尽可能多的信息,以及订单的详细信息。

Webpay Plus 捕获延迟

在此模式下,将保留客户的信用卡余额,预留额度,但不会立即完成交易,直到商家通过捕获延迟确认购买并将其通知Transbank。

延迟交易开始

要启动捕获延迟交易,使用与Webpay Plus Normal相同的流程,但是证书是通知Transbank将启动一个捕获延迟交易的部分,因此这仅在这些方面有所不同。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
use Freshwork\Transbank\RedirectorHelper;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay Diferido  
$bag = CertificationBagFactory::integrationWebpayDeferred();  
  
$plus = TransbankServiceFactory::deferred($bag);  
  
// Para transacciones normales, solo puedes añadir una linea de detalle de transacción.  
$plus->addTransactionDetail(10000, 'Orden824201'); // Monto e identificador de la orden  
  
// Debes además, registrar las URLs a las cuales volverá el cliente durante y después del flujo de Webpay  
$response = $plus->initTransaction('http://test.dev/response', 'http://test.dev/thanks');  
  
// Utilidad para generar formulario y realizar redirección POST  
echo RedirectorHelper::redirectHTML($response->url, $response->token);  

以下步骤与Webpay Plus Normal完全相同,即返回到中途URL,然后返回到最终URL

捕获交易的全部或部分金额

在完成初始流程后,我们将有最多7个日历日来执行捕获,因为超过这个时间,信用卡的预留将被撤销,额度将被释放。

我们可以捕获全部或部分保留的金额,为此我们需要指定在初始流程中提供的授权代码和订单标识符。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay Diferido  
$bag = CertificationBagFactory::integrationWebpayDeferred();  
  
$plus = TransbankServiceFactory::captureNullify($bag);  
  
$authCode = 'this-auth-code-is-an-example';  
  
// Puedes capturar el monto total o parcial  
$plus->capture($authCode, 'Orden824201', 5000); // Código de autorización, identificador de la orden y monto  

取消

只有使用信用卡进行的Webpay(正常或捕获延迟)交易可以通过Web服务进行取消。

取消可以是全部或部分,后者仅允许在正常销售(VN)模式下进行。

要进行取消,我们需要知道先前授权的金额、授权代码和订单标识符。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay Normal  
$bag = CertificationBagFactory::normal();  
  
$plus = TransbankServiceFactory::captureNullify($bag);  
  
$authorizedAmount = '10000';  
$authCode = 'this-auth-code-is-an-example';  
  
// Puedes capturar el monto total o parcial  
$plus->nullify($authCode, $authorizedAmount, 'Orden824201', 2000); // Solo se anularán $2.000 y quedará un balance de $8.000  

OneClick

允许持卡人在不每次在购买时输入信用卡信息的情况下在商家处进行支付。

客户注册

要使用OneClick,用户必须注册其信用卡卡,为此,我们将向Transbank提供客户的用户名(或唯一标识符)、电子邮件地址以及一个返回URL(用户在完成注册后返回的URL),使用initInscription方法,该方法将返回一个TOKEN和一个URL

用户必须使用HTTP POST请求重定向到该URL,使用我们提供的token作为数据。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
use Freshwork\Transbank\RedirectorHelper;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay OneClick.  
$certificationBag = CertificationBagFactory::integrationOneClick();  
$oneClick = TransbankServiceFactory::oneclick($certificationBag);  
  
  
// Informamos a Transbank que se iniciará un proceso de inscripción para un usuario  
$response = $oneClick->initInscription('username', 'user@company.cl', 'http://misitio.cl/webpayresponse');  
  
// Utilidad para generar formulario y realizar redirección POST  
echo RedirectorHelper::redirectHTML($response->urlWebpay, $response->token);  
  

pago seguro webpay

完成注册

用户在Webpay完成流程后,将被重定向到我们之前提供的返回URL。

在此重定向过程中,将向您发送一个包含在HTTP POST请求正文中的TOKEN(重定向),键为TBK_TOKEN$_POST['TBK_TOKEN']),但您无需担心这一点,因为finishInscription方法会内部捕获此值。

使用此方法(finishInscription)我们将向Transbank请求有关注册和用户标识符的信息,以便进行后续的收费,但我们也必须验证注册是否成功。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay OneClick.  
$certificationBag = CertificationBagFactory::integrationOneClick();  
$oneClick = TransbankServiceFactory::oneclick($certificationBag);  
  
$response = $oneClick->finishInscription($token);  
  
if($response->responseCode == 0)  
    // Inscripción exitosa  
}  
  
var_dump($response);  

var_dump

将Transbank提供的token(tbkUser)与您的客户关联非常重要,因为这将用于后续的收费。

对信用卡进行收费

要为之前注册的信用卡进行收费,您必须使用authorize方法,使用Transbank在之前步骤中提供的与您的客户关联的token,客户的用户名或唯一标识符、金额和订单号(特殊格式)。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay OneClick.  
$certificationBag = CertificationBagFactory::integrationOneClick();  
$oneClick = TransbankServiceFactory::oneclick($certificationBag);  
  
// Identificador único de la compra generado por el comercio. Debe ser timestamp [yyyymmddhhMMss] + un correlativo de tres dígitos.  
// Ej: Para la tercera transacción realizada el día 15 de julio de 2011 a las 11:55:50 la orden de compra sería: 20110715115550003.  
$buyOrder = date('ymdhis') . str_pad(1, 3, '0', STR_PAD_LEFT);  
  
// Token provisto por Transbank para identificar a tu cliente  
$authToken = '9bf43307-6fa0-4b3b-888d-f36b6d040162'; //$user->tbkToken;  
  
try {  
    $response = $oneClick->authorize(1000, $buyOrder, 'username', $authToken);  
} catch (\Exception $e) {  
    // No se pudo realizar el cargo  
}  
  
var_dump($response);  

sp dev authorize

撤销收费

在某些情况下,我们需要取消一个订单,为此我们必须使用codeReverseOneClick方法以及订单号。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay OneClick.  
$certificationBag = CertificationBagFactory::integrationOneClick();  
$oneClick = TransbankServiceFactory::oneclick($certificationBag);  
  
// Ej: $response = $oneClick->codeReverseOneClick('20110715115550003');  
$response = $oneClick->codeReverseOneClick($buyOrder);  

取消订阅信用卡

如果您的客户希望取消其信用卡订阅,您必须使用removeUser方法通知Transbank,并提供与该客户关联的token和用户名或唯一标识符。

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
  
include 'vendor/autoload.php';  
  
// Obtenemos los certificados y llaves para utilizar el ambiente de integración de Webpay OneClick.  
$certificationBag = CertificationBagFactory::integrationOneClick();  
$oneClick = TransbankServiceFactory::oneclick($certificationBag);  
  
$response = $oneClick->removeUser($userToken, $username);  

PatPass

Webpay通过PatPass进行的授权交易对应于一个使用信用卡进行定期支付请求的注册,其中第一次支付即时解决,后续的支付每月执行。PatPass有一个到期日期或终止日期,必须与其他数据一起提供以进行此交易。交易可以是美元和比索,在后一种情况下,可以发送以UF为单位的金额,Webpay将在向持卡人收费时将其转换为比索。

Patpass的过程与正常或Mall交易相同,但在此处必须在调用init方法之前完成注册信息addInscriptionInfo
请注意,建议使用方法init而不是initInscription

init

<?php  
  
use Freshwork\Transbank\CertificationBagFactory;  
use Freshwork\Transbank\TransbankServiceFactory;  
use Freshwork\Transbank\RedirectorHelper;  
  
include 'vendor/autoload.php';  
  
$bag = CertificationBagFactory::integrationPatPass();  
  
$patpass = TransbankServiceFactory::patpass($bag);  
  
$patpass->addTransactionDetail(1000, '50'); //Amount & BuyOrder  
  
//Id del servicio a contratar, Rut cliente, Nombre, Apellido, Segundo apellido, Email cliente, Celular Cliente, Fecha termino contrato, Email comercio  
$patpass->addInscriptionInfo('serviceID', '11.111.111-5', 'Gonzalo', 'De Spirito', 'Zúñiga', 'gonzalo@email.com',  
    '987654321', '2017-12-01', 'contacto@comercio.cl');  
  
$response = $patpass->init('http://test.dev/response', 'http://test.dev/thanks');  
echo RedirectorHelper::redirectHTML($response->url, $response->token);  

response

  
$response = $patpass->getTransactionResult();  
//If everything goes well (check stock, check amount, etc) you can call acknowledgeTransaction to accept the payment. Otherwise, the transaction is reverted in 30 seconds.  
//Si todo está bien, peudes llamar a acknowledgeTransaction. Si no se llama a este método, la transaccion se reversará en 30 segundos.  
$plus->acknowledgeTransaction();  
  
//Redirect back to Webpay Flow and then to the thanks page  
return RedirectorHelper::redirectBackNormal($response->urlRedirection);  

Laravel

如果您使用Laravel来集成此库,您会知道我们包含了一个ServiceProvider,以便您的集成更简单、更有序。

安装

Laravel > 5.5

如果您使用Laravel 5.5或更高版本,您不需要做任何事情。Service Provider将自动使用Laravel的自动发现功能。

如果您使用Laravel < 5.5

您必须在config/app.php中的$providers数组中添加此Service Provider。

$providers = [
	...
	\Freshwork\Transbank\Laravel\WebpayServiceProvider::class
]

可选地,您可以使用以下命令创建配置文件config/webpay.phpphp artisan vendor:publish --provider="Freshwork\Transbank\Laravel\WebpayServiceProvider"

使用Laravel

此集成的优点在于,您可以使用Laravel的依赖注入系统使用服务(例如webpay normal、patpass、one click等)。例如,在controller的方法中,只需添加服务(例如WebpayNormal)即可,service provider将负责创建CertificationBag(如果Laravel的环境是local则为集成,如果环境是production则为生产证书)。

// routes/web.php
Route::get('/checkout', 'CheckoutController@initTransaction')->name('checkout');  
Route::post('/checkout/webpay/response', 'CheckoutController@response')->name('checkout.webpay.response');  
Route::post('/checkout/webpay/finish', 'CheckoutController@finish')->name('checkout.webpay.finish');
// app\Http\Controllers\CheckoutController.php
namespace App\Http\Controllers;

use Freshwork\Transbank\WebpayNormal;
class CheckoutController extends Controller  
{
	public function initTransaction(WebpayNormal $webpayNormal)
	{
		$webpayNormal->addTransactionDetail(1500, 'order-' . rand(1000, 9999));  
		$response = $webpayNormal->initTransaction(route('checkout.webpay.response'), route('checkout.webpay.finish')); 
		// Probablemente también quieras crear una orden o transacción en tu base de datos y guardar el token ahí.
		  
		return RedirectorHelper::redirectHTML($response->url, $response->token);
	}

	public function response(WebpayPatPass $webpayPatPass)  
	{  
	  $result = $webpayPatPass->getTransactionResult();  
	  session(['response' => $result]);  
	  // Revisar si la transacción fue exitosa ($result->detailOutput->responseCode === 0) o fallida para guardar ese resultado en tu base de datos. 
	  
	  return RedirectorHelper::redirectBackNormal($result->urlRedirection);  
	}

	public function finish()  
	{
	  dd($_POST, session('response'));  
	  // Acá buscar la transacción en tu base de datos y ver si fue exitosa o fallida, para mostrar el mensaje de gracias o de error según corresponda
	}
}
// app\Http\Middleware\VerifyCsrfToken.php
<?php  
  
namespace App\Http\Middleware;  

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;  
  
class VerifyCsrfToken extends Middleware  
{  
  /**  
 * Indicates whether the XSRF-TOKEN cookie should be set on the response. * * @var bool  
 */  protected $addHttpCookie = true;  
  
  /**  
 * The URIs that should be excluded from CSRF verification. * * @var array  
 */  protected $except = [  
  '/checkout/webpay/response',  //Agregar esta línea. Cambiar a tu ruta
  '/checkout/webpay/finish', //Agregar esta línea. Cambiar a tu ruta
 ];}

Laravel: 迁移到生产环境

要将系统切换到生产环境,需要在.env文件中更改APP_ENV=production,或者创建一个TBK_ENV=production

如果不存在TBK_ENV,则将使用APP_ENV

生产环境证书

默认情况下,系统将在以下文件夹中查找生产环境证书:storage/app/certs/

Webpay Normal 私钥:storage/app/certs/normal/client.key 证书:storage/app/certs/normal/client.crt

Webpay OneClick 私钥:storage/app/certs/oneclick/client.key 证书:storage/app/certs/oneclick/client.crt

Webpay PatPass 私钥:storage/app/certs/patpass/client.key 证书:storage/app/certs/patpass/client.crt

Webpay Captura Diferida 私钥:storage/app/certs/deferred/client.key 证书:storage/app/certs/deferred/client.crt

日志

对于与Transbank的证书认证过程,很多时候需要请求已完成的交易记录,而这个库提供了一个实用工具来简化此过程。

使用TransbankCertificationLogger时,您需要指定存储这些记录的路径,并在LoggerFactory中设置其实例。

另一种选择是创建自己的实现,使用LoggerInterface接口。

<?php  
      
use Freshwork\Transbank\Log\LoggerFactory;  
use Freshwork\Transbank\Log\TransbankCertificationLogger;  
  
include 'vendor/autoload.php';  
  
LoggerFactory::setLogger(new TransbankCertificationLogger('/dir/to/save/logs'));  
  
// ...  
  

内部将生成多个记录,其中包括

  • 调用SOAP方法时的输入数据

  • 生成的并已签名的XML

  • 接收到的XML

  • 接收到的对象

  • 错误,例如证书验证失败。

如果您需要记录更多信息,可以使用

LogHandler::log($data, $level = LoggerInterface::LEVEL_INFO, $type = null)

<?php  
  
use Freshwork\Transbank\Log\LogHandler;  
use Freshwork\Transbank\Log\LoggerInterface;  
  
LogHandler::log('Comenzando proceso de pago', LoggerInterface::LEVEL_INFO);   
LogHandler::log('Error!!', LoggerInterface::LEVEL_ERROR, 'mensajes_internos');   
LogHandler::log(['datos' => 'más datos', 'otros_datos']);   

CertificationBag

这是一个用于封装证书和私钥的类,旨在通过库简化对这些元素的管理。
必须使用CertificationBag,因为它包含与Transbank通信进行加密和验证响应所需的所有必要数据。

<?php  
  
use Freshwork\Transbank\CertificationBag;  
use Freshwork\Transbank\CertificationBagFactory;  
  
// Integración / Desarrollo  
$bag = new CertificationBag(  
   'path/to/cert/597020000000.key',  
   'path/to/cert/597020000000.crt',  
   null,  
   CertificationBag::INTEGRATION  
);  
  
// Producción  
$bag = new CertificationBag(  
   'path/to/cert/597020000001.key',  
   'path/to/cert/597020000001.crt',  
   null,  
   CertificationBag::PRODUCTION  
);  
  
//También se puede crear usando la clase CertificationBagFactory, que permite crear instancias de CertificationBag de manera más simple  
CertificationBagFactory::production('path/to/cert/597020000001.key', 'path/to/cert/597020000001.crt');  
  
//O si queremos crear un certification bag que venga con los certificados de integración para webpaynormal  
CertificationBagFactory::integrationWebpayNormal();  
  

拥有一个CertificationBag后,可以创建Webpay服务的实例,例如:WebpayOneClickWebService

<?php  
  
use Freshwork\Transbank\CertificationBag;  
use Freshwork\Transbank\WebpayOneClickWebService;  
  
$bag = new CertificationBag(  
    '/path/to/597020000000.key',  
    '/path/to/597020000000.crt'  
);  
$bag->setEnvironment(CertificationBag::INTEGRATION);  
  
$oneClickService = new WebpayOneClickWebService($bag);  

过渡到生产环境

切换到生产环境时,需要注意的是,Transbank将要求创建一对密钥(私钥和公钥),使用商家代码作为通用名(CN)。
一旦通过认证流程,Transbank将向您发送生成此证书的说明,尽管您也可以在这里找到它们:https://transbankdevelopers.cl/documentacion/como_empezar#credenciales-en-webpay

证书生成器

为了简化此过程,我创建了一个Web应用程序,它允许您通过简单的表单创建生产环境证书。您可以在这里输入:https://certificados.digitalpartner.cl/

一旦您发送了您生成的证书,您需要等待确认,以确认它们确实已经加载到其服务器上。

最后,在收到确认后,您就可以在实时模式下使用您的实现(使用真实资金)。在您的项目代码中,您需要进行的唯一更改是更改CertificationBag中的证书。

示例:如果您正在实现Webpay Normal,则必须删除此行(或您用于创建CertificationBag的任何行)

//Eliminar esta  
$bag = CertificationBagFactory::integrationWebpayNormal();  
...  

并替换为以下内容

//Reemplazar por esta  
$bag = CertificationBagFactory::production('tu/llave/privada.key', 'path/a/tu/ceriticado_publico.crt');  
...  

重要的是仅更改您使用的CertificationBag,而不是使用集成环境中的CertificationBag,您必须创建一个用于生产环境的。

测试数据

以下是用于在集成环境中测试的卡数据。

image

信用卡 VISA(将被批准)

卡号 4051885600446623

CVV 123

有效期:任何日期

信用卡 MASTERCARD(将被拒绝)

卡号 5186059559590568

CVV 123

有效期:任何日期

借记卡

卡号:任何卡号

银行凭证

RUT 11.111.111-1

密码 123

captura de pantalla 2016-07-15 a las 6 28 41 p m

Simplepay开发

Freshwork Studio提供支持

许可证和版权

您可以免费使用此软件包,没有任何限制。虽然它很流行,但我们实施了“邮政软件”许可证。如果您在生产环境中使用此软件包并喜欢其功能,我们非常感谢您能发送一张您所在城市/社区的明信片、一张感谢信或一张超8胶片。

地址
姓名:Gonzalo De Spirito
General Bustamante 24,办公室N,Providencia。
智利,