├── .built ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── __init__.py ├── docker-compose.yml ├── oneclick ├── __init__.py └── routes.py ├── oneclick_deferred ├── __init__.py └── routes.py ├── patpass_by_webpay ├── __init__.py └── routes.py ├── patpass_comercio ├── __init__.py └── routes.py ├── requirements.txt ├── tbk_examples.py ├── templates ├── include │ ├── footer.html │ └── header.html ├── index.html ├── oneclick │ ├── authorize.html │ ├── deferred │ │ ├── authorize.html │ │ ├── authorized.html │ │ ├── capture.html │ │ ├── delete.html │ │ ├── deleted.html │ │ ├── start.html │ │ ├── started.html │ │ ├── status.html │ │ └── status_form.html │ ├── delete.html │ ├── deleted.html │ ├── refund.html │ ├── start.html │ ├── started.html │ ├── status.html │ └── status_form.html ├── patpass_comercio │ ├── finish_inscription.html │ ├── start_inscription.html │ ├── status.html │ └── voucher_displayed.html ├── transaccion_completa │ ├── create.html │ ├── created.html │ ├── deferred │ │ ├── capture.html │ │ ├── commit.html │ │ ├── create.html │ │ ├── created.html │ │ └── status.html │ ├── installments.html │ ├── refund-form.html │ ├── status-form.html │ ├── transaction_committed.html │ ├── transaction_refunded.html │ └── transaction_status.html ├── transaccion_completa_mall │ ├── create.html │ ├── created.html │ ├── deferred │ │ ├── capture.html │ │ ├── commit.html │ │ ├── create.html │ │ ├── created.html │ │ ├── installments.html │ │ ├── status.html │ │ ├── transaction_committed.html │ │ └── transaction_refunded.html │ ├── installments.html │ ├── refund-form.html │ ├── status-form.html │ ├── transaction_committed.html │ ├── transaction_refunded.html │ └── transaction_status.html └── webpay │ ├── patpass │ ├── commit.html │ ├── create.html │ ├── status-form.html │ └── status.html │ ├── plus │ ├── commit.html │ ├── create.html │ ├── refund-form.html │ ├── refund.html │ ├── status-form.html │ └── status.html │ ├── plus_deferred │ ├── capture.html │ ├── commit.html │ ├── create.html │ ├── refund-form.html │ ├── refund.html │ ├── status-form.html │ └── status.html │ ├── plus_mall │ ├── commit.html │ ├── create.html │ ├── created.html │ ├── refund-form.html │ ├── refund.html │ ├── status-form.html │ └── status.html │ └── plus_mall_deferred │ ├── capture.html │ ├── commit.html │ ├── create.html │ ├── created.html │ ├── refund-form.html │ ├── refund.html │ ├── status-form.html │ └── status.html ├── transaccion_completa ├── __init__.py └── routes.py ├── transaccion_completa_deferred ├── __init__.py └── routes.py ├── transaccion_completa_mall ├── __init__.py └── routes.py ├── transaccion_completa_mall_deferred ├── __init__.py └── routes.py ├── webpay_plus ├── __init__.py └── routes.py ├── webpay_plus_deferred ├── __init__.py └── routes.py ├── webpay_plus_mall ├── __init__.py └── routes.py └── webpay_plus_mall_deferred ├── __init__.py └── routes.py /.built: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransbankDevelopers/transbank-sdk-python-webpay-rest-example/0caa3ee714b8ff4e9f481e19f2cda2a7756b916b/.built -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *$py.class 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | wheels/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | MANIFEST 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *.cover 46 | .hypothesis/ 47 | .pytest_cache/ 48 | cover/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | .vscode 107 | 108 | .DS_Store 109 | 110 | .idea 111 | 112 | .pipped -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.7 2 | RUN apk --update add bash nano 3 | RUN pip install --upgrade pip 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, Transbank Developers 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | all: build run 4 | 5 | run: build 6 | docker-compose run --rm --service-ports web 7 | 8 | build: .built .pipped 9 | 10 | .built: Dockerfile 11 | docker-compose build 12 | touch .built 13 | 14 | .pipped: requirements.txt 15 | docker-compose run web pip install -r requirements.txt 16 | touch .pipped 17 | 18 | logs: 19 | docker-compose logs 20 | 21 | clean: 22 | docker-compose rm 23 | rm .built 24 | rm .pipped 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Transbank SDK Webpay REST example project for Python 2 | 3 | ### Requirements 4 | 5 | You need to have `docker` and `docker-compose`installed 6 | 7 | #### How to run this example project 8 | 9 | You can run this project by typing `make` on your Terminal 10 | 11 | ### Troubleshooting 12 | 13 | Currently this example project uses local repos as dependencies, exposing them from your computer to 14 | the docker container. If the SDK is not found, you can check `docker-compose.yml` on the repo's root and check the 15 | `volumes` entry, to verify that the origin path (the one with `{$HOME}`) matches the location of the SDK on your local 16 | machine 17 | 18 | ### Alternative Way to run the example project 19 | 20 | If you don't want to use docker, you can run the example project by following these steps: 21 | 22 | - Execute the command `python3 -m venv venv` 23 | - Activate the virtual environment with `source venv/bin/activate` 24 | - Install the dependencies with `pip install -r requirements.txt` 25 | - Run the example with python `__init__.py` 26 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, Config, app, render_template 2 | import os 3 | 4 | APP_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 | TEMPLATE_PATH = os.path.join(APP_PATH, 'templates/') 6 | 7 | 8 | def create_app(config_class=Config): 9 | app = Flask(__name__) 10 | app.config.from_object(config_class) 11 | 12 | from transaccion_completa import bp as transaccion_completa_bp 13 | from transaccion_completa_deferred import bp as transaccion_completa_deferred_bp 14 | from patpass_by_webpay import bp as patpass_by_webpay_bp 15 | from webpay_plus import bp as webpay_plus_bp 16 | from webpay_plus_mall import bp as webpay_plus_mall_bp 17 | from webpay_plus_deferred import bp as webpay_plus_deferred_bp 18 | from webpay_plus_mall_deferred import bp as webpay_plus_mall_deferred_bp 19 | from transaccion_completa_mall import bp as transaccion_completa_mall_bp 20 | from transaccion_completa_mall_deferred import bp as transaccion_completa_mall_deferred_bp 21 | from patpass_comercio import bp as patpass_comercio_bp 22 | from oneclick import bp as oneclick_bp 23 | from oneclick_deferred import bp as oneclick_deferred_bp 24 | 25 | app.register_blueprint(transaccion_completa_bp, url_prefix='/fulltransaction') 26 | app.register_blueprint(transaccion_completa_deferred_bp, url_prefix='/fulltransaction-deferred') 27 | app.register_blueprint(transaccion_completa_mall_deferred_bp, url_prefix='/mallfulltransaction-deferred') 28 | app.register_blueprint(patpass_by_webpay_bp, url_prefix='/patpass-webpay') 29 | app.register_blueprint(webpay_plus_bp, url_prefix="/webpay-plus") 30 | app.register_blueprint(webpay_plus_mall_bp, url_prefix="/webpay-plus-mall") 31 | app.register_blueprint(webpay_plus_deferred_bp, url_prefix="/webpay-plus-deferred") 32 | app.register_blueprint(webpay_plus_mall_deferred_bp, url_prefix="/webpay-plus-mall-deferred") 33 | app.register_blueprint(transaccion_completa_mall_bp, url_prefix='/mallfulltransaction/') 34 | app.register_blueprint(patpass_comercio_bp, url_prefix='/patpass-comercio') 35 | app.register_blueprint(oneclick_bp, url_prefix='/oneclick-mall') 36 | app.register_blueprint(oneclick_deferred_bp, url_prefix='/oneclick-mall-deferred') 37 | 38 | @app.route('/') 39 | def index(): 40 | return render_template('index.html') 41 | 42 | return app 43 | 44 | 45 | create_app().run() 46 | #create_app() -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | web: &web 4 | tty: true 5 | stdin_open: true 6 | build: 7 | context: . 8 | dockerfile: Dockerfile 9 | command: flask run --host=0.0.0.0 10 | volumes: 11 | - .:/app 12 | volumes_from: 13 | - python_cache 14 | ports: 15 | - "5000:5000" 16 | environment: 17 | - FLASK_APP=/app/__init__.py 18 | - FLASK_ENV=development 19 | 20 | python_cache: 21 | image: tiangolo/uwsgi-nginx-flask:python3.7-alpine3.7 22 | volumes: 23 | - /usr/local/lib/python3.7/site-packages -------------------------------------------------------------------------------- /oneclick/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | bp = Blueprint('oneclick', __name__) 4 | 5 | from oneclick import routes 6 | -------------------------------------------------------------------------------- /oneclick/routes.py: -------------------------------------------------------------------------------- 1 | from transbank.error.transbank_error import TransbankError 2 | from transbank.webpay.oneclick.request import MallTransactionAuthorizeDetails 3 | 4 | from oneclick import bp 5 | from flask import render_template, request 6 | from transbank.webpay.oneclick.mall_inscription import MallInscription 7 | from transbank.webpay.oneclick.mall_transaction import MallTransaction 8 | 9 | import random 10 | 11 | 12 | @bp.route('start', methods=['GET']) 13 | def show_start(): 14 | hostname = request.headers.get('Host') 15 | protocol = request.scheme 16 | endpoint = protocol + "://" + hostname + "/oneclick-mall/finish" 17 | return render_template('/oneclick/start.html', endpoint=endpoint) 18 | 19 | 20 | @bp.route('status', methods=['GET']) 21 | def show_status(): 22 | return render_template('/oneclick/status_form.html') 23 | 24 | 25 | @bp.route('start', methods=['POST']) 26 | def start(): 27 | user_name = request.form.get('user_name') 28 | email = request.form.get('email') 29 | response_url = request.form.get('response_url') 30 | 31 | ins = MallInscription() 32 | resp = ins.start( 33 | username=user_name, 34 | email=email, 35 | response_url=response_url) 36 | 37 | return render_template('oneclick/started.html', resp=resp, req=request.form) 38 | 39 | 40 | @bp.route('finish', methods=['GET']) 41 | def finish(): 42 | req = request.form 43 | token = request.args.get('TBK_TOKEN') 44 | 45 | ins = MallInscription() 46 | resp = ins.finish(token) 47 | buy_order_1 = str(random.randrange(1000000, 99999999)) 48 | buy_order_2 = str(random.randrange(1000000, 99999999)) 49 | buy_order = str(random.randrange(1000000, 99999999)) 50 | commerce_code_1 = '597055555542' 51 | commerce_code_2 = '597055555543' 52 | return render_template('oneclick/authorize.html', req=req, resp=resp, buy_order_1=buy_order_1, 53 | buy_order_2=buy_order_2, buy_order=buy_order, token=token, commerce_code_1=commerce_code_1, 54 | commerce_code_2=commerce_code_2) 55 | 56 | @bp.route('finish', methods=['POST']) 57 | def finish_error(): 58 | req = request.form 59 | token = request.form.get('TBK_TOKEN') 60 | 61 | ins = MallInscription() 62 | resp = ins.finish(token=token) 63 | buy_order_1 = str(random.randrange(1000000, 99999999)) 64 | buy_order_2 = str(random.randrange(1000000, 99999999)) 65 | buy_order = str(random.randrange(1000000, 99999999)) 66 | commerce_code_1 = '597055555542' 67 | commerce_code_2 = '597055555543' 68 | return render_template('oneclick/authorize.html', req=req, resp=resp, buy_order_1=buy_order_1, 69 | buy_order_2=buy_order_2, buy_order=buy_order, token=token, commerce_code_1=commerce_code_1, 70 | commerce_code_2=commerce_code_2) 71 | 72 | @bp.route('delete', methods=['POST']) 73 | def delete(): 74 | req = request.form 75 | 76 | tbk_user = request.form.get('tbk_user') 77 | user_name = request.form.get('user_name') 78 | 79 | try: 80 | ins = MallInscription() 81 | resp = ins.delete(tbk_user, user_name) 82 | return render_template('oneclick/deleted.html', req=req, resp=resp) 83 | except TransbankError as e: 84 | print("ERROR_MESSAGE: {}".format(e.message)) 85 | 86 | @bp.route('authorize', methods=['POST']) 87 | def authorize(): 88 | req = request.form 89 | tbk_user = request.form.get('tbk_user') 90 | user_name = request.form.get('user_name') 91 | buy_order = request.form.get('buy_order') 92 | token_inscription = request.form.get('token_inscription') 93 | 94 | commerce_code = request.form.get('details[0][commerce_code]') 95 | buy_order_child = request.form.get('details[0][buy_order]') 96 | installments_number = request.form.get('details[0][installments_number]') 97 | amount = request.form.get('details[0][amount]') 98 | 99 | commerce_code2 = request.form.get('details[1][commerce_code]') 100 | buy_order_child2 = request.form.get('details[1][buy_order]') 101 | installments_number2 = request.form.get('details[1][installments_number]') 102 | amount2 = request.form.get('details[1][amount]') 103 | 104 | details = MallTransactionAuthorizeDetails(commerce_code, buy_order_child, installments_number, amount) \ 105 | .add(commerce_code2, buy_order_child2, installments_number2, amount2) 106 | 107 | tx = MallTransaction() 108 | resp = tx.authorize(username=user_name, tbk_user=tbk_user, parent_buy_order=buy_order, details=details) 109 | return render_template('oneclick/refund.html', req=req, resp=resp, details=details.details, buy_order=buy_order, 110 | tbk_user=tbk_user) 111 | 112 | 113 | @bp.route('refund', methods=['POST']) 114 | def refund(): 115 | req = request.form 116 | buy_order = request.form.get('buy_order') 117 | child_commerce_code = request.form.get('child_commerce_code') 118 | child_buy_order = request.form.get('child_buy_order') 119 | amount = request.form.get('amount') 120 | tbk_user = request.form.get('tbk_user') 121 | tx = MallTransaction() 122 | resp = tx.refund(buy_order, child_commerce_code, child_buy_order, amount) 123 | return render_template('oneclick/delete.html', req=req, resp=resp, tbk_user=tbk_user) 124 | 125 | 126 | 127 | 128 | 129 | @bp.route('status', methods=['POST']) 130 | def status(): 131 | buy_order = request.form.get('buy_order') 132 | tx = MallTransaction() 133 | resp = tx.status(buy_order) 134 | 135 | return render_template('oneclick/status.html', resp=resp, req=request.form) 136 | -------------------------------------------------------------------------------- /oneclick_deferred/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | bp = Blueprint('oneclick_deferred', __name__) 4 | 5 | from oneclick_deferred import routes 6 | -------------------------------------------------------------------------------- /oneclick_deferred/routes.py: -------------------------------------------------------------------------------- 1 | from transbank.error.transbank_error import TransbankError 2 | from transbank.webpay.oneclick.request import MallTransactionAuthorizeDetails 3 | 4 | from oneclick_deferred import bp 5 | from flask import render_template, request 6 | from transbank.webpay.oneclick.mall_inscription import MallInscription 7 | from transbank.webpay.oneclick.mall_transaction import MallTransaction 8 | from transbank.common.integration_commerce_codes import IntegrationCommerceCodes 9 | from transbank.common.integration_type import IntegrationType 10 | from transbank.common.integration_api_keys import IntegrationApiKeys 11 | from transbank.common.options import WebpayOptions 12 | 13 | import random 14 | 15 | 16 | @bp.route('start', methods=['GET']) 17 | def show_start(): 18 | hostname = request.headers.get('Host') 19 | protocol = request.scheme 20 | endpoint = protocol + "://" + hostname + "/oneclick-mall-deferred/finish" 21 | return render_template('/oneclick/deferred/start.html', endpoint=endpoint) 22 | 23 | 24 | @bp.route('status', methods=['GET']) 25 | def show_status(): 26 | return render_template('/oneclick/deferred/status_form.html') 27 | 28 | 29 | @bp.route('start', methods=['POST']) 30 | def start(): 31 | user_name = request.form.get('user_name') 32 | email = request.form.get('email') 33 | response_url = request.form.get('response_url') 34 | 35 | ins = MallInscription(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 36 | resp = ins.start( 37 | username=user_name, 38 | email=email, 39 | response_url=response_url) 40 | 41 | return render_template('oneclick/deferred/started.html', resp=resp, req=request.form) 42 | 43 | 44 | @bp.route('finish', methods=['GET']) 45 | def finish(): 46 | req = request.form 47 | token = request.args.get('TBK_TOKEN') 48 | 49 | ins = MallInscription(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 50 | resp = ins.finish(token) 51 | buy_order_1 = str(random.randrange(1000000, 99999999)) 52 | buy_order_2 = str(random.randrange(1000000, 99999999)) 53 | buy_order = str(random.randrange(1000000, 99999999)) 54 | commerce_code_1 = IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED_CHILD1 55 | commerce_code_2 = IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED_CHILD2 56 | return render_template('oneclick/deferred/authorize.html', req=req, resp=resp, buy_order_1=buy_order_1, 57 | buy_order_2=buy_order_2, buy_order=buy_order, token=token, commerce_code_1=commerce_code_1, 58 | commerce_code_2=commerce_code_2) 59 | 60 | 61 | @bp.route('finish', methods=['POST']) 62 | def finish_error(): 63 | req = request.form 64 | token = request.form.get('TBK_TOKEN') 65 | 66 | ins = MallInscription(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 67 | resp = ins.finish(token=token) 68 | buy_order_1 = str(random.randrange(1000000, 99999999)) 69 | buy_order_2 = str(random.randrange(1000000, 99999999)) 70 | buy_order = str(random.randrange(1000000, 99999999)) 71 | commerce_code_1 = IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED_CHILD1 72 | commerce_code_2 = IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED_CHILD2 73 | return render_template('oneclick/deferred/authorize.html', req=req, resp=resp, buy_order_1=buy_order_1, 74 | buy_order_2=buy_order_2, buy_order=buy_order, token=token, commerce_code_1=commerce_code_1, 75 | commerce_code_2=commerce_code_2) 76 | 77 | 78 | @bp.route('delete', methods=['POST']) 79 | def delete(): 80 | req = request.form 81 | 82 | tbk_user = request.form.get('tbk_user') 83 | user_name = request.form.get('user_name') 84 | 85 | try: 86 | ins = MallInscription(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 87 | resp = ins.delete(tbk_user, user_name) 88 | return render_template('oneclick/deferred/deleted.html', req=req, resp=resp) 89 | except TransbankError as e: 90 | print("ERROR_MESSAGE: {}".format(e.message)) 91 | 92 | 93 | @bp.route('authorize', methods=['POST']) 94 | def authorize(): 95 | req = request.form 96 | tbk_user = request.form.get('tbk_user') 97 | user_name = request.form.get('user_name') 98 | buy_order = request.form.get('buy_order') 99 | token_inscription = request.form.get('token_inscription') 100 | 101 | commerce_code = request.form.get('details[0][commerce_code]') 102 | buy_order_child = request.form.get('details[0][buy_order]') 103 | installments_number = request.form.get('details[0][installments_number]') 104 | amount = request.form.get('details[0][amount]') 105 | 106 | commerce_code2 = request.form.get('details[1][commerce_code]') 107 | buy_order_child2 = request.form.get('details[1][buy_order]') 108 | installments_number2 = request.form.get('details[1][installments_number]') 109 | amount2 = request.form.get('details[1][amount]') 110 | 111 | details = MallTransactionAuthorizeDetails(commerce_code, buy_order_child, installments_number, amount) \ 112 | .add(commerce_code2, buy_order_child2, installments_number2, amount2) 113 | 114 | tx = MallTransaction(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 115 | response = tx.authorize(username=user_name, tbk_user=tbk_user, parent_buy_order=buy_order, details=details) 116 | return render_template('oneclick/deferred/authorized.html', request=req, response=response, details=details.details, buy_order=buy_order, 117 | tbk_user=tbk_user) 118 | 119 | 120 | @bp.route('refund', methods=['POST']) 121 | def refund(): 122 | req = request.form 123 | buy_order = request.form.get('buy_order') 124 | child_commerce_code = request.form.get('child_commerce_code') 125 | child_buy_order = request.form.get('child_buy_order') 126 | amount = request.form.get('amount') 127 | tbk_user = request.form.get('tbk_user') 128 | tx = MallTransaction(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 129 | resp = tx.refund(buy_order, child_commerce_code, child_buy_order, amount) 130 | return render_template('oneclick/deferred/delete.html', req=req, resp=resp, tbk_user=tbk_user) 131 | 132 | 133 | @bp.route('status', methods=['POST']) 134 | def status(): 135 | buy_order = request.form.get('buy_order') 136 | tx = MallTransaction(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 137 | resp = tx.status(buy_order) 138 | 139 | return render_template('oneclick/deferred/status.html', resp=resp, req=request.form) 140 | 141 | 142 | @bp.route('capture', methods=['POST']) 143 | def capture(): 144 | buy_order = request.form.get('buy_order') 145 | authorization_code = request.form.get('authorization_code') 146 | commerce_code = request.form.get('commerce_code') 147 | capture_amount = request.form.get('capture_amount') 148 | tx = MallTransaction(WebpayOptions(IntegrationCommerceCodes.ONECLICK_MALL_DEFERRED, IntegrationApiKeys.WEBPAY, IntegrationType.TEST)) 149 | response = tx.capture(commerce_code, buy_order, authorization_code, capture_amount) 150 | request_data = { 151 | "buy_order": buy_order, 152 | "authorization_code": authorization_code, 153 | "commerce_code": commerce_code, 154 | "capture_amount": capture_amount 155 | } 156 | return render_template('oneclick/deferred/capture.html', request= request_data, response=response) 157 | 158 | -------------------------------------------------------------------------------- /patpass_by_webpay/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | # from transaccion_completa.transaccion_completa import TransaccionCompleta 4 | 5 | bp = Blueprint('patpass_by_webpay', __name__) 6 | 7 | from patpass_by_webpay import routes 8 | -------------------------------------------------------------------------------- /patpass_by_webpay/routes.py: -------------------------------------------------------------------------------- 1 | import string 2 | import random 3 | from transbank.error.transbank_error import TransbankError 4 | from patpass_by_webpay import bp 5 | from flask import render_template, request 6 | from transbank.patpass_by_webpay.transaction import Transaction 7 | 8 | 9 | @bp.route('create') 10 | def patpass_webpay_create(): 11 | print("Patpass Webpay Transaction.create") 12 | buy_order = str(random.randrange(1000000, 99999999)) 13 | session_id = str(random.randrange(1000000, 99999999)) 14 | return_url = request.url_root + 'patpass-webpay/commit' 15 | service_id = random_string(20) 16 | card_holder_id = random_string(20) 17 | card_holder_name = random_string(20) 18 | card_holder_last_name1 = random_string(20) 19 | card_holder_last_name2 = random_string(20) 20 | card_holder_mail = '{}@{}.com'.format(random_string(10), random_string(7)) 21 | commerce_mail = '{}@{}.com'.format(random_string(10), random_string(7)) 22 | cellphone_number = random.randrange(1000000, 99999999) 23 | expiration_date = '2222-11-11' 24 | 25 | create_request = { 26 | 'buy_order': buy_order, 27 | 'session_id': session_id, 28 | 'return_url': return_url, 29 | 'service_id': service_id, 30 | 'card_holder_id': card_holder_id, 31 | 'card_holder_name': card_holder_name, 32 | 'card_holder_last_name1': card_holder_last_name1, 33 | 'card_holder_last_name2': card_holder_last_name2, 34 | 'card_holder_mail': card_holder_mail, 35 | 'commerce_mail': commerce_mail, 36 | 'cellphone_number': cellphone_number, 37 | 'expiration_date': expiration_date, 38 | } 39 | 40 | tx = Transaction() 41 | response = tx.create(buy_order, session_id, 1000, return_url, service_id, card_holder_id, card_holder_name, 42 | card_holder_last_name1, card_holder_last_name2, card_holder_mail, cellphone_number, 43 | expiration_date, commerce_mail, False) 44 | 45 | print(response) 46 | 47 | return render_template('webpay/patpass/create.html', request=create_request, response=response) 48 | 49 | 50 | @bp.route('commit', methods=["GET"]) 51 | def patpass_webpay_commit(): 52 | token = request.args.get("token_ws") 53 | print("commit for token_ws: {}".format(token)) 54 | 55 | tx = Transaction() 56 | response = tx.commit(token=token) 57 | print("response: {}".format(response)) 58 | 59 | return render_template('webpay/patpass/commit.html', token=token, response=response) 60 | 61 | 62 | @bp.route("status-form", methods=["GET"]) 63 | def patpass_webpay_status_form(): 64 | return render_template("webpay/patpass/status-form.html") 65 | 66 | 67 | @bp.route("status", methods=["POST"]) 68 | def patpass_webpay_status(): 69 | token = request.form.get("token_ws") 70 | try: 71 | tx = Transaction() 72 | response = tx.status(token) 73 | print(response) 74 | return render_template("webpay/patpass/status.html", token=token, response=response) 75 | except TransbankError as e: 76 | print(e.message) 77 | 78 | 79 | def random_string(string_length=10): 80 | """Generate a random string of fixed length """ 81 | letters = string.ascii_lowercase 82 | return ''.join(random.choice(letters) for i in range(string_length)) 83 | -------------------------------------------------------------------------------- /patpass_comercio/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | bp = Blueprint('patpass_comercio', __name__) 4 | 5 | from patpass_comercio import routes 6 | -------------------------------------------------------------------------------- /patpass_comercio/routes.py: -------------------------------------------------------------------------------- 1 | import string 2 | import random 3 | from transbank.error.transbank_error import TransbankError 4 | from transbank.patpass_comercio.inscription import Inscription 5 | 6 | from patpass_comercio import bp 7 | from flask import render_template, request 8 | 9 | 10 | @bp.route('start') 11 | def patpass_comercio_inscription(): 12 | print("Patpass Comercio Transaction.inscription") 13 | name = 'nombre' 14 | first_last_name = 'apellido' 15 | second_last_name = 'apellido' 16 | rut = '14140066-5' 17 | return_url = 'http://return_url' #request.url_root + 'patpass-comercio/end-inscription' 18 | service_id = random.randrange(1000000, 99999999) 19 | final_url = 'http://final_url' #request.url_root + 'patpass-comercio/voucher-generated' 20 | max_amount = 0 21 | phone_number = random.randrange(1000000, 99999999) 22 | mobile_number = random.randrange(1000000, 99999999) 23 | patpass_name = random_string(20) 24 | person_email = '{}@{}.com'.format(random_string(10), random_string(7)) 25 | commerce_mail = '{}@{}.com'.format(random_string(10), random_string(7)) 26 | address = random_string(20) 27 | city = random_string(20) 28 | 29 | 30 | inscription_request = { 31 | 'return_url': return_url, 32 | 'name': name, 33 | 'first_last_name': first_last_name, 34 | 'second_last_name': second_last_name, 35 | 'rut': rut, 36 | 'service_id': service_id, 37 | 'final_url': final_url, 38 | 'max_amount': max_amount, 39 | 'phone_number': phone_number, 40 | 'mobile_number': mobile_number, 41 | 'patpass_name': patpass_name, 42 | 'person_email': person_email, 43 | 'commerce_mail': commerce_mail, 44 | 'address': address, 45 | 'city': city, 46 | } 47 | 48 | ins = Inscription().configure_for_testing() 49 | response = ins.start(return_url, name, first_last_name, second_last_name, rut, service_id, None, 50 | max_amount, phone_number, mobile_number, patpass_name, 51 | person_email, commerce_mail, address, city) 52 | 53 | print(response) 54 | 55 | return render_template('patpass_comercio/start_inscription.html', request=inscription_request, response=response) 56 | 57 | 58 | @bp.route('end-inscription', methods=["POST"]) 59 | def patpass_comercio_end_inscription(): 60 | token = request.form.get("j_token") 61 | print("commit for token_ws: {}".format(token)) 62 | 63 | return render_template('patpass_comercio/finish_inscription.html', token=token) 64 | 65 | 66 | @bp.route("status", methods=["POST"]) 67 | def patpass_comercio_status(): 68 | token = request.form.get("tokenComercio") 69 | try: 70 | ins = Inscription() 71 | response = ins.status(token) 72 | print(response) 73 | return render_template("patpass_comercio/status.html", token=token, response=response) 74 | except TransbankError as e: 75 | print(e.message) 76 | 77 | 78 | @bp.route('voucher-generated', methods=["POST"]) 79 | def patpass_comercio_voucher_generated(): 80 | return render_template('patpass_comercio/voucher_displayed.html') 81 | 82 | 83 | def random_string(string_length=10): 84 | """Generate a random string of fixed length """ 85 | letters = string.ascii_lowercase 86 | return ''.join(random.choice(letters) for i in range(string_length)) 87 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | transbank-sdk==5.0.0 -------------------------------------------------------------------------------- /tbk_examples.py: -------------------------------------------------------------------------------- 1 | from main import create_app 2 | app = create_app() 3 | -------------------------------------------------------------------------------- /templates/include/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /templates/include/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |Service | 13 |Create | 14 |Refund | 15 |Status | 16 |
---|---|---|---|
Webpay Plus | 21 |Crear Transacción | 22 |Reembolsar Transacción | 23 |Consultar Estado Transacción | 24 |
Webpay Plus Mall | 27 |Crear Transacción | 28 |Reembolsar Transacción | 29 |Consultar Estado Transacción | 30 |
Webpay Plus Captura Diferida | 33 |Crear Transacción | 34 |Reembolsar Transacción | 35 |Consultar Estado Transacción | 36 |
Webpay Plus Mall Deferred | 40 |Crear Transacción | 41 |Reembolsar Transacción | 42 |Consultar Estado Transacción | 43 |
Oneclick Mall | 47 |Comenzar Inscripción | 48 |49 | | Consultar Estado Transacción | 50 |
Oneclick Mall Deferred | 54 |Comenzar Inscripción | 55 |56 | | 57 | |
Transacción Completa | 61 |Crear Transacción | 62 |Reembolsar Transacción | 63 |Consultar Estado Transacción | 64 |
Transacción Completa Deferred | 67 |Crear Transacción | 68 |- | 69 |- | 70 |
Patpass-webpay | 73 |Crear Transacción | 74 |- | 75 |Consultar Estado Transacción | 76 |
Transacción Completa Mall | 80 |Crear Transacción | 81 |Reembolsar Transacción | 82 |Consultar Estado Transacción | 83 |
Transacción Completa Mall Deferred | 87 |Crear Transacción | 88 |- | 89 |- | 90 |
Patpass Comercio | 94 |Crear Transacción | 95 |96 | | 97 | |
Subscription finished successfully
31 |Sesion iniciada con éxito en Patpass Comercio
36 |Voucher displayed successfully with Patpass comercio
17 |Reembolso realizado con éxito.
33 |