diff --git a/tests/internet_banking_tests.py b/tests/internet_banking_tests.py new file mode 100644 index 0000000..ef9998e --- /dev/null +++ b/tests/internet_banking_tests.py @@ -0,0 +1,172 @@ +import random +import unittest +import os + +import requests +from requests import codes + +from faker import Faker +fake = Faker() + +import veritranspay +from veritranspay import request, veritrans, payment_types, response +from veritranspay.response import status + +from . import fixtures + + +SANDBOX_CLIENT_KEY = os.environ.get('SANDBOX_CLIENT_KEY', None) +SANDBOX_SERVER_KEY = os.environ.get('SANDBOX_SERVER_KEY', None) +RUN_ALL_ACCEPTANCE_TESTS = os.environ.get('RUN_ALL_ACCEPTANCE_TESTS', False) + + +class InternetBankingTests_Base(object): + + def setUp(self): + if None in [SANDBOX_CLIENT_KEY, SANDBOX_SERVER_KEY]: + self.skipTest("Live credentials not provided -- skipping tests") + if not RUN_ALL_ACCEPTANCE_TESTS and \ + self.VERSION != veritranspay.__version__: + self.skipTest("Skipping this version of tests") + + expected = fixtures.CC_REQUEST + self.expected = expected + + self.trans_details = request.TransactionDetails( + order_id="".join([fake.random_letter() for _ in range(10)]), + gross_amount=expected['transaction_details']['gross_amount']) + + self.cust_details = request.CustomerDetails( + first_name=expected['customer_details']['first_name'], + last_name=expected['customer_details']['last_name'], + email=expected['customer_details']['email'], + phone=expected['customer_details']['phone'], + billing_address=request.Address( + **expected['customer_details']['billing_address']), + shipping_address=request.Address( + **expected['customer_details']['shipping_address']) + ) + + self.item_details = \ + [request.ItemDetails(item_id=item['id'], + price=item['price'], + quantity=item['quantity'], + name=item['name']) + for item + in expected['item_details']] + + +class MandiriClickpayTests_v0_9(InternetBankingTests_Base, unittest.TestCase): + + VERSION = '0.9' + + def test_mandiri_click_pay_charge(self): + # 1: Create a sandbox gateway + gateway = veritrans.VTDirect( + server_key=SANDBOX_SERVER_KEY, + sandbox_mode=True) + + # 2: Set payment type Internet Banking from Mandiri Click pay + mandiri_clickpay = payment_types.MandiriClickpay( + card_number="4111111111111111", + input1="1111111111", + input2="145000", + input3="54321", + token="000000") + + # 3: Create a charge request + charge_req = request.ChargeRequest( + charge_type=mandiri_clickpay, + transaction_details=self.trans_details, + customer_details=self.cust_details, + item_details=self.item_details) + + # 4: Submit our request + resp = gateway.submit_charge_request(charge_req) + + self.assertIsInstance(resp, response.MandiriChargeResponse) + self.assertEqual(status.SUCCESS, resp.status_code) + + +class CimbClicksTests_v0_9(InternetBankingTests_Base, unittest.TestCase): + + VERSION = '0.9' + + def test_cimb_clicks_charge(self): + # 1: Create a sandbox gateway + gateway = veritrans.VTDirect( + server_key=SANDBOX_SERVER_KEY, + sandbox_mode=True) + + # 2: Set payment type to Cimb Clicks internet banking. + cimb_clicks = payment_types.CimbClicks( + description="Purchase of a special event item") + + # 3: Create a charge request + charge_req = request.ChargeRequest( + charge_type=cimb_clicks, + transaction_details=self.trans_details, + customer_details=self.cust_details, + item_details=self.item_details) + + # 4: Submit our request + resp = gateway.submit_charge_request(charge_req) + + self.assertIsInstance(resp, response.CimbsChargeResponse) + self.assertEqual(status.CHALLENGE, resp.status_code) + + +class BCAKlikPayTests_v0_9(InternetBankingTests_Base, unittest.TestCase): + + VERSION = '0.9' + + def test_bcaklikpay_charger(self): + # 1: Create a sandbox gateway + gateway = veritrans.VTDirect( + server_key=SANDBOX_SERVER_KEY, + sandbox_mode=True) + + # 2: Set Internet banking BCA Klik pay + bca_klikpay = payment_types.BCAKlikPay(type_id=1, description="Pembelian barang") + + # 3: Create a charge request + charge_req = request.ChargeRequest( + charge_type=bca_klikpay, + transaction_details=self.trans_details, + customer_details=self.cust_details, + item_details=self.item_details) + + # 4: Submit our request + resp = gateway.submit_charge_request(charge_req) + + self.assertIsInstance(resp, response.BCAKlikPayChargeResponse) + self.assertEqual(status.CHALLENGE, resp.status_code) + + +class KlikBCATests_v0_9(InternetBankingTests_Base, unittest.TestCase): + + VERSION = '0.9' + + def test_klikbca_charger(self): + # 1: Create a sandbox gateway + gateway = veritrans.VTDirect( + server_key=SANDBOX_SERVER_KEY, + sandbox_mode=True) + + # 2: Set Internet banking Klik BCA + klik_bca = payment_types.KlikBCA(user_id="midtrans1014", # error + description="Testing transaction") + + # 3: Create a charge request + charge_req = request.ChargeRequest( + charge_type=klik_bca, + transaction_details=self.trans_details, + customer_details=self.cust_details, + item_details=self.item_details) + + # 4: Submit our request + resp = gateway.submit_charge_request(charge_req) + + self.assertIsInstance(resp, response.KlikBCAChargeResponse) + self.assertEqual(status.CHALLENGE, resp.status_code) + diff --git a/tests/live_tests.py b/tests/live_tests.py index 0d3a6a6..5d524d9 100644 --- a/tests/live_tests.py +++ b/tests/live_tests.py @@ -179,9 +179,9 @@ def test_preauth_capture(self): pass -class PermataVA_AcceptanceTests_v0_8(unittest.TestCase): +class PermataVA_AcceptanceTests_v0_9(unittest.TestCase): - VERSION = '0.8' + VERSION = '0.9' def setUp(self): if None in [SANDBOX_CLIENT_KEY, SANDBOX_SERVER_KEY]: @@ -246,9 +246,9 @@ def test_virtualaccountpermata(self): self.assertEqual(self.trans_details.order_id, resp.order_id) -class BriEpay_AcceptanceTests_v0_8(unittest.TestCase): +class BriEpay_AcceptanceTests_v0_9(unittest.TestCase): - VERSION = '0.8' + VERSION = '0.9' def setUp(self): if None in [SANDBOX_CLIENT_KEY, SANDBOX_SERVER_KEY]: @@ -309,9 +309,9 @@ def test_briepay(self): self.assertEqual(self.trans_details.order_id, resp.order_id) -class MandiriVA_AcceptanceTests_v0_8(unittest.TestCase): +class MandiriVA_AcceptanceTests_v0_9(unittest.TestCase): - VERSION = '0.8' + VERSION = '0.9' def setUp(self): if None in [SANDBOX_CLIENT_KEY, SANDBOX_SERVER_KEY]: diff --git a/tests/payment_types_tests.py b/tests/payment_types_tests.py index be1c6d6..dd20dff 100644 --- a/tests/payment_types_tests.py +++ b/tests/payment_types_tests.py @@ -3,7 +3,7 @@ from faker import Faker from veritranspay.payment_types import CreditCard, Indomaret, VirtualAccountPermata, VirtualAccountBca, \ - VirtualAccountBni, VirtualAccountMandiri, BriEpay + VirtualAccountBni, VirtualAccountMandiri, BriEpay, MandiriClickpay, CimbClicks, BCAKlikPay, KlikBCA fake = Faker() @@ -149,3 +149,75 @@ def test_serialization(self): } self.assertDictEqual(expected, bri.serialize()) + + +class BCAKliPayTest(unittest.TestCase): + def test_serialization(self): + bca_klikpay = BCAKlikPay(type_id=1, description="Pembelian Barang") + + expected = { + 'payment_type': 'bca_klikpay', + 'bca_klikpay': { + 'type': 1, + 'description': 'Pembelian Barang' + } + } + + self.assertDictEqual(expected, bca_klikpay.serialize()) + + +class KlikBCATest(unittest.TestCase): + + def test_serialization(self): + klik_bca = KlikBCA(user_id="midtrans1012", description="testing transaction") + + expected = { + 'payment_type': 'bca_klikbca', + 'bca_klikbca': { + 'description': 'testing transaction', + 'user_id': 'midtrans1012' + } + } + + self.assertDictEqual(expected, klik_bca.serialize()) + + +class MandiriClickpayTest(unittest.TestCase): + + def test_serialization(self): + data_init = { + 'card_number': '4111111111111111', + 'input1': '1111111111', + 'input2': '145000', + 'input3': '54321', + 'token': '000000' + } + + mandiri_clickpay = MandiriClickpay(**data_init) + + expected = { + 'payment_type': 'mandiri_clickpay', + 'mandiri_clickpay': { + 'card_number': '4111111111111111', + 'input1': '1111111111', + 'input2': '145000', + 'input3': '54321', + 'token': '000000' + } + } + + self.assertDictEqual(expected, mandiri_clickpay.serialize()) + + +class CimbClicksTest(unittest.TestCase): + def test_serialization(self): + cimb_clicks = CimbClicks(description='Purchase of a special event item') + + expected = { + 'payment_type': 'cimb_clicks', + 'cimb_clicks': { + 'description': 'Purchase of a special event item' + } + } + + self.assertDictEqual(expected, cimb_clicks.serialize()) \ No newline at end of file diff --git a/tests/response_bca_klikbca_tests.py b/tests/response_bca_klikbca_tests.py new file mode 100644 index 0000000..302180a --- /dev/null +++ b/tests/response_bca_klikbca_tests.py @@ -0,0 +1,37 @@ +from unittest import TestCase + +from veritranspay.response.response import EpayBriChargeResponse + + +class EpayBriChargeResponseTests_v0_9(TestCase): + """ + https://api-docs.midtrans.com/#epay-bri + """ + + def setUp(self): + # example response data from + # https://api-docs.midtrans.com/#permata-virtual-account + self.response_json = { + "status_code": "201", + "status_message": "OK, BCA KlikPay transaction is successful", + "transaction_id": "ada84cd9-2233-4c67-877a-01884eece45e", + "order_id": "orderid-01", + "redirect_url": "https://api.sandbox.veritrans.co.id/v3/bca/klikpay/redirect/ada84cd9-2233-4c67-877a-01884eece45e", + "gross_amount": "11000.00", + "payment_type": "bca_klikpay", + "transaction_time": "2016-06-19 15:42:36", + "transaction_status": "pending", + "fraud_status": "accept" + } + + self.parsed_response = EpayBriChargeResponse(**self.response_json) + + def test_status_code(self): + self.assertEqual(201, self.parsed_response.status_code) + + def test_payment_type(self): + self.assertEqual('bca_klikpay', self.parsed_response.payment_type) + + def test_redirect_url(self): + self.assertEqual('https://api.sandbox.veritrans.co.id/v3/bca/klikpay/redirect/ada84cd9-2233-4c67-877a-01884eece45e', self.parsed_response.redirect_url) + diff --git a/tests/response_bcaklikpay_tests.py b/tests/response_bcaklikpay_tests.py new file mode 100644 index 0000000..cd55a35 --- /dev/null +++ b/tests/response_bcaklikpay_tests.py @@ -0,0 +1,31 @@ +from unittest import TestCase + +from veritranspay.response import BCAKlikPayChargeResponse + + +class BCAKlikPayChargeResponseTests_v0_9(TestCase): + + def setUp(self): + # example response data from + # http://api-docs.midtrans.com/#bca-klikpay + self.response_json = { + "status_code": "201", + "status_message": "OK, BCA KlikPay transaction is successful", + "transaction_id": "ada84cd9-2233-4c67-877a-01884eece45e", + "order_id": "orderid-01", + "redirect_url": "https://api.sandbox.veritrans.co.id/v3/bca/klikpay/redirect/ada84cd9-2233-4c67-877a-01884eece45e", + "gross_amount": "11000.00", + "payment_type": "bca_klikpay", + "transaction_time": "2016-06-19 15:42:36", + "transaction_status": "pending", + "fraud_status": "accept" + } + + self.parsed_response = BCAKlikPayChargeResponse(**self.response_json) + + def test_status_code(self): + self.assertEqual(201, self.parsed_response.status_code) + + def test_payment_type(self): + self.assertEqual('bca_klikpay', self.parsed_response.payment_type) + diff --git a/tests/response_cimb_klikpay_tests.py b/tests/response_cimb_klikpay_tests.py new file mode 100644 index 0000000..83bb2f0 --- /dev/null +++ b/tests/response_cimb_klikpay_tests.py @@ -0,0 +1,30 @@ +from unittest import TestCase + +from veritranspay.response import CimbsChargeResponse + + +class CimbsChargeResponseTests_v0_9(TestCase): + + def setUp(self): + # example response data from + # http://api-docs.midtrans.com/#cimb-clicks + self.response_json = { + "status_code": "201", + "status_message": "Success, CIMB Clicks transaction is successful", + "redirect_url": "https://api.midtrans.com/cimb-clicks/request?id=226f042f-020e-4829-8bd7-2de64b8673ce", + "transaction_id": "226f042f-020e-4829-8bd7-2de64b8673ce", + "order_id": "1000156414164125", + "gross_amount": "392127.00", + "payment_type": "cimb_clicks", + "transaction_time": "2016-06-19 16:41:25", + "transaction_status": "pending" + } + + self.parsed_response = CimbsChargeResponse(**self.response_json) + + def test_status_code(self): + self.assertEqual(201, self.parsed_response.status_code) + + def test_payment_type(self): + self.assertEqual('cimb_clicks', self.parsed_response.payment_type) + diff --git a/tests/response_klikbca_tests.py b/tests/response_klikbca_tests.py new file mode 100644 index 0000000..7acb73c --- /dev/null +++ b/tests/response_klikbca_tests.py @@ -0,0 +1,31 @@ +from unittest import TestCase + +from veritranspay.response import KlikBCAChargeResponse + + +class KlikBCAChargeResponseTests_v0_9(TestCase): + + def setUp(self): + # example response data from + # -- + self.response_json = { + "status_code": "201", + "status_message": "Success, KlikBCA transaction is successful", + "redirect_url": "https://www.klikbca.com", + "transaction_id": "c0ba3583-5111-45a5-9f1c-84c9de7cb2f6", + "order_id": "3176440", + "gross_amount": "50000.00", + "payment_type": "bca_klikbca", + "transaction_time": "2016-06-19 15:53:25", + "transaction_status": "pending", + "approval_code": "tes01" + } + + self.parsed_response = KlikBCAChargeResponse(**self.response_json) + + def test_status_code(self): + self.assertEqual(201, self.parsed_response.status_code) + + def test_payment_type(self): + self.assertEqual('bca_klikbca', self.parsed_response.payment_type) + diff --git a/tests/response_mandiri_clickpay_tests.py b/tests/response_mandiri_clickpay_tests.py new file mode 100644 index 0000000..ed9a440 --- /dev/null +++ b/tests/response_mandiri_clickpay_tests.py @@ -0,0 +1,32 @@ +from unittest import TestCase + +from veritranspay.response import MandiriChargeResponse + + +class MandiriChargeResponseTests_v0_9(TestCase): + + def setUp(self): + # example response data from + # http://api-docs.midtrans.com/#mandiri-clickpay + self.response_json = { + "status_code": "200", + "status_message": "Success, Mandiri Clickpay transaction is successful", + "transaction_id": "3bdddabe-a4ea-4233-81cc-09578178909f", + "order_id": "100248319", + "gross_amount": "156216.00", + "payment_type": "mandiri_clickpay", + "transaction_time": "2016-06-19 15:56:45", + "transaction_status": "settlement", + "fraud_status": "accept", + "approval_code": "166JF5644001", + "masked_card": "461699-9495" + } + + self.parsed_response = MandiriChargeResponse(**self.response_json) + + def test_status_code(self): + self.assertEqual(200, self.parsed_response.status_code) + + def test_payment_type(self): + self.assertEqual('mandiri_clickpay', self.parsed_response.payment_type) + diff --git a/veritranspay/__init__.py b/veritranspay/__init__.py index 376df7c..e46aee1 100644 --- a/veritranspay/__init__.py +++ b/veritranspay/__init__.py @@ -1 +1 @@ -__version__ = '0.8' +__version__ = '0.9' diff --git a/veritranspay/payment_types.py b/veritranspay/payment_types.py index df653bc..e5f4371 100644 --- a/veritranspay/payment_types.py +++ b/veritranspay/payment_types.py @@ -138,23 +138,94 @@ class BriEpay(PaymentTypeBase): PAYMENT_TYPE_KEY = 'bri_epay' -# -# NOTE: -# The following types are not yet supported! -# They will be added to the documentation as support is added -# - - class MandiriClickpay(PaymentTypeBase): - # http://docs.veritranspay.co.id/sandbox/charge.html#vtdirect-mandiri + """ + A payment made with a Mandiri Click Pay. + + http://api-docs.midtrans.com/#mandiri-clickpay + """ PAYMENT_TYPE_KEY = 'mandiri_clickpay' - def __init__(self, card_number, input1, input2, input3): - raise NotImplementedError("Only CreditCard is implemented.") + def __init__(self, card_number, input1, input2, input3, token): + self.card_number = card_number + self.input1 = input1 + self.input2 = input2 + self.input3 = input3 + self.token = token + + def serialize(self): + rv = super(MandiriClickpay, self).serialize() + rv[self.PAYMENT_TYPE_KEY].update({ + 'card_number': self.card_number, + 'input1': self.input1, + 'input2': self.input2, + 'input3': self.input3, + 'token': self.token + }) + + return rv + class CimbClicks(PaymentTypeBase): - # http://docs.veritranspay.co.id/sandbox/charge.html#vtdirect-cimb + """ + A payment made with a Cimb Clicks. + + http://api-docs.midtrans.com/#cimb-clicks + """ + PAYMENT_TYPE_KEY = 'cimb_clicks' def __init__(self, description): - raise NotImplementedError("Only CreditCard is implemented.") + self.description = description + + def serialize(self): + rv = super(CimbClicks, self).serialize() + rv[self.PAYMENT_TYPE_KEY].update({ + 'description': self.description + }) + + return rv + + +class BCAKlikPay(PaymentTypeBase): + """ + A payment made with a BCA Klik Pay. + + http://api-docs.midtrans.com/#bca-klikpay + """ + PAYMENT_TYPE_KEY = 'bca_klikpay' + + def __init__(self, type_id, description): + self.type = type_id + self.description = description + + def serialize(self): + rv = super(BCAKlikPay, self).serialize() + rv[self.PAYMENT_TYPE_KEY].update({ + 'type': self.type, + 'description': self.description + }) + + return rv + + +class KlikBCA(PaymentTypeBase): + """ + A payment made with a BCA Klik Pay. + + http://api-docs.midtrans.com/#klikbca + """ + PAYMENT_TYPE_KEY = 'bca_klikbca' + + def __init__(self, user_id, description): + self.user_id = user_id + self.description = description + + def serialize(self): + rv = super(KlikBCA, self).serialize() + rv[self.PAYMENT_TYPE_KEY].update({ + 'user_id': self.user_id, + 'description': self.description}) + + return rv + diff --git a/veritranspay/response/__init__.py b/veritranspay/response/__init__.py index 3a1baf5..6930ec9 100644 --- a/veritranspay/response/__init__.py +++ b/veritranspay/response/__init__.py @@ -1,4 +1,7 @@ # just to make this accessible from a more sane location from .response import * from .response import build_charge_response, StatusResponse, ApproveResponse, \ - CancelResponse, ResponseBase, CreditCardChargeResponse + CancelResponse, ResponseBase, CreditCardChargeResponse, CimbsChargeResponse, \ + MandiriChargeResponse, BCAKlikPayChargeResponse, KlikBCAChargeResponse, IndomaretChargeResponse, \ + VirtualAccountBcaChargeResponse, VirtualAccountBniChargeResponse, VirtualAccountChargeResponse,\ + VirtualAccountMandiriChargeResponse, VirtualAccountPermataChargeResponse diff --git a/veritranspay/response/response.py b/veritranspay/response/response.py index 7552ec2..e4d867c 100644 --- a/veritranspay/response/response.py +++ b/veritranspay/response/response.py @@ -13,11 +13,11 @@ - http://docs.veritrans.co.id/sandbox/charge.html ''' __all__ = ['ResponseBase', 'ChargeResponseBase', 'CreditCardChargeResponse', - 'IndomaretChargeResponse', 'CimbsChargeResponse', 'MandiriChargeResponse', - 'StatusResponse', 'CancelResponse', 'VirtualAccountChargeResponse', + 'IndomaretChargeResponse', 'CimbsChargeResponse', 'MandiriChargeResponse', 'BCAKlikPayChargeResponse', + 'KlikBCAChargeResponse', 'StatusResponse', 'CancelResponse', 'VirtualAccountChargeResponse', 'VirtualAccountPermataChargeResponse', 'VirtualAccountBcaChargeResponse', 'VirtualAccountBniChargeResponse', 'VirtualAccountMandiriChargeResponse', 'EpayBriChargeResponse', - 'build_charge_response', 'ApproveResponse', ] + 'build_charge_response', 'ApproveResponse',] from veritranspay import mixins, helpers, payment_types @@ -97,19 +97,49 @@ def __init__(self, *args, **kwargs): class CimbsChargeResponse(ChargeResponseBase): - # not implemented -- not documented + """ + Cimb charge response when using payment_types is chimb clicks. + + http://api-docs.midtrans.com/#cimb-clicks + """ def __init__(self, *args, **kwargs): super(CimbsChargeResponse, self).__init__(*args, **kwargs) self.redirect_url = kwargs.get('redirect_url', None) class MandiriChargeResponse(ChargeResponseBase): - # not implemented -- not documented + """ + Mandiri charge response when using payment_types is mandiri click pay. + + http://api-docs.midtrans.com/#mandiri-clickpay + """ def __init__(self, *args, **kwargs): super(MandiriChargeResponse, self).__init__(*args, **kwargs) self.masked_card = kwargs.get('masked_card', None) +class BCAKlikPayChargeResponse(ChargeResponseBase): + """ + BCA charge response when using payment_types is bca_klikpay. + + http://api-docs.midtrans.com/#bca-klikpay + """ + def __init__(self, *args, **kwargs): + super(BCAKlikPayChargeResponse, self).__init__(*args, **kwargs) + self.redirect_url = kwargs.get("redirect_url", None) + + +class KlikBCAChargeResponse(ChargeResponseBase): + """ + BCA charge response when using payment_types is bca_klikbca. + + http://api-docs.midtrans.com/#klikbca + """ + def __init__(self, *args, **kwargs): + super(KlikBCAChargeResponse, self).__init__(*args, **kwargs) + self.redirect_url = kwargs.get("redirect_url", None) + + class VirtualAccountChargeResponse(ChargeResponseBase): # not implemented -- not documented def __init__(self, *args, **kwargs): @@ -209,9 +239,13 @@ def build_charge_response(request, *args, **kwargs): elif isinstance(request.charge_type, payment_types.BriEpay): return EpayBriChargeResponse(*args, **kwargs) elif isinstance(request.charge_type, payment_types.CimbClicks): - raise NotImplementedError("CimbClicks not yet supported.") + return CimbsChargeResponse(*args, **kwargs) elif isinstance(request.charge_type, payment_types.MandiriClickpay): - raise NotImplementedError("MandiriClickpay not yet supported") + return MandiriChargeResponse(*args, **kwargs) + elif isinstance(request.charge_type, payment_types.BCAKlikPay): + return BCAKlikPayChargeResponse(*args, **kwargs) + elif isinstance(request.charge_type, payment_types.KlikBCA): + return KlikBCAChargeResponse(*args, **kwargs) else: return ChargeResponseBase(*args, **kwargs) @@ -304,4 +338,4 @@ def __init__(self, *args, **kwargs): self.redirect_url = kwargs.get('redirect_url', None) self.gross_amount = \ helpers.parse_veritrans_amount( - kwargs.get('gross_amount', None)) + kwargs.get('gross_amount', None)) \ No newline at end of file