Skip to content

Commit 7f8b615

Browse files
authored
Merge pull request #22 from omarxp/tokenization-and-subscription
add API subscription & Gopay Tokenization implementation
2 parents 5fd6c5c + 3d0c2c3 commit 7f8b615

11 files changed

+903
-22
lines changed

README.md

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ snap = midtransclient.Snap(
123123
server_key='YOUR_SERVER_KEY',
124124
client_key='YOUR_CLIENT_KEY'
125125
)
126-
# Build API parameter
126+
# Prepare parameter
127127
param = {
128128
"transaction_details": {
129129
"order_id": "test-transaction-123",
@@ -191,7 +191,7 @@ snap = midtransclient.Snap(
191191
server_key='YOUR_SERVER_KEY',
192192
client_key='YOUR_CLIENT_KEY'
193193
)
194-
# Build API parameter
194+
# Prepare parameter
195195
param = {
196196
"transaction_details": {
197197
"order_id": "test-transaction-123",
@@ -277,7 +277,7 @@ core_api = midtransclient.Snap(
277277
server_key='YOUR_SERVER_KEY',
278278
client_key='YOUR_CLIENT_KEY'
279279
)
280-
# Build API parameter
280+
# Prepare parameter
281281
param = {
282282
"payment_type": "credit_card",
283283
"transaction_details": {
@@ -303,6 +303,108 @@ The credit card charge result may contains `redirect_url` for 3DS authentication
303303
For full example on Credit Card 3DS transaction refer to:
304304
- [Flask App examples](/examples/flask_app) that implement Snap & Core Api
305305

306+
### 2.2.D Subscription API
307+
308+
You can see some Subscription API examples [here](examples/subscription), [Subscription API Docs](https://api-docs.midtrans.com/#subscription-api)
309+
310+
#### Subscription API for Credit Card
311+
312+
To use subscription API for credit card, you should first obtain the 1-click saved token, [refer to this docs.](https://docs.midtrans.com/en/core-api/advanced-features?id=recurring-transaction-with-subscriptions-api)
313+
314+
You will receive `saved_token_id` as part of the response when the initial card payment is accepted (will also available in the HTTP notification's JSON), [refer to this docs.](https://docs.midtrans.com/en/core-api/advanced-features?id=sample-3ds-authenticate-json-response-for-the-first-transaction)
315+
316+
```python
317+
# Create Subscription API instance
318+
core_api = midtransclient.CoreApi(
319+
is_production=False,
320+
server_key='YOUR_SERVER_KEY',
321+
client_key='YOUR_CLIENT_KEY'
322+
)
323+
# Prepare parameter
324+
param = {
325+
"name": "SUBSCRIPTION-STARTER-1",
326+
"amount": "100000",
327+
"currency": "IDR",
328+
"payment_type": "credit_card",
329+
"token": "436502qFfqfAQKScMtPRPdZDOaeg7199",
330+
"schedule": {
331+
"interval": 1,
332+
"interval_unit": "month",
333+
"max_interval": 3,
334+
"start_time": "2021-10-01 07:25:01 +0700"
335+
},
336+
"metadata": {
337+
"description": "Recurring payment for STARTER 1"
338+
},
339+
"customer_details": {
340+
"first_name": "John A",
341+
"last_name": "Doe A",
342+
"email": "[email protected]",
343+
"phone": "+62812345678"
344+
}
345+
}
346+
create_subscription_response = core_api.create_subscription(param)
347+
348+
subscription_id_response = create_subscription_response['id']
349+
# get subscription by subscription_id
350+
get_subscription_response = core_api.get_subscription(subscription_id_response)
351+
352+
# disable subscription by subscription_id
353+
disable_subscription_response = core_api.disable_subscription(subscription_id_response)
354+
355+
# enable subscription by subscription_id
356+
enable_subscription_response = core_api.enable_subscription(subscription_id_response)
357+
358+
# update subscription by subscription_id
359+
update_param = {
360+
"name": "SUBSCRIPTION-STARTER-1-UPDATE",
361+
"amount": "100000",
362+
"currency": "IDR",
363+
"token": "436502qFfqfAQKScMtPRPdZDOaeg7199",
364+
"schedule": {
365+
"interval": 1
366+
}
367+
update_subscription_response = core_api.update_subscription(subscription_id_response, update_param)
368+
```
369+
370+
#### Subscription API for Gopay
371+
372+
To use subscription API for gopay, you should first link your customer gopay account with gopay tokenization API, [refer to this section](#22e-tokenization-api)
373+
374+
You will receive gopay payment token using `get_payment_account` API call
375+
376+
You can see some Subscription API examples [here](examples/subscription)
377+
378+
### 2.2.E Tokenization API
379+
You can see some Tokenization API examples [here](examples/tokenization), [Tokenization API Docs](https://api-docs.midtrans.com/#gopay-tokenization)
380+
381+
```python
382+
# Create Tokenization API instance
383+
core_api = midtransclient.CoreApi(
384+
is_production=False,
385+
server_key='YOUR_SERVER_KEY',
386+
client_key='YOUR_CLIENT_KEY'
387+
)
388+
# Prepare parameter
389+
param = {
390+
"payment_type": "gopay",
391+
"gopay_partner": {
392+
"phone_number": "81234567891",
393+
"country_code": "62",
394+
"redirect_url": "https://mywebstore.com/gopay-linking-finish" #please update with your redirect URL
395+
}
396+
}
397+
398+
# link payment account
399+
link_payment_account_response = core_api.link_payment_account(param)
400+
401+
# get payment account
402+
get_payment_account_response = core_api.get_payment_account(active_account_id)
403+
404+
# unlink account
405+
unlink_payment_account_response = core_api.unlink_payment_account(active_account_id)
406+
```
407+
306408
### 2.3 Handle HTTP Notification
307409

308410
> **IMPORTANT NOTE**: To update transaction status on your backend/database, **DO NOT** solely rely on frontend callbacks! For security reason to make sure the status is authentically coming from Midtrans, only update transaction status based on HTTP Notification or API Get Status.
@@ -479,6 +581,8 @@ Under the hood this API wrapper is using [Requests](https://github.com/requests/
479581
Examples are available on [/examples](/examples) folder.
480582
There are:
481583
- [Core Api examples](/examples/core_api)
584+
- [Subscription examples](/examples/subscription)
585+
- [Tokenization examples](/examples/tokenization)
482586
- [Snap examples](/examples/snap)
483587
- [Flask App examples](/examples/flask_app) that implement Snap & Core Api
484588

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# This is just for very basic implementation reference, in production, you should validate the incoming requests and implement your backend more securely.
2+
import midtransclient
3+
import datetime
4+
5+
# Initialize core api client object
6+
# You can find it in Merchant Portal -> Settings -> Access keys
7+
core_api = midtransclient.CoreApi(
8+
is_production=False,
9+
server_key='YOUR_SERVER_KEY',
10+
client_key='YOUR_CLIENT_KEY'
11+
)
12+
13+
# To use API subscription for credit card, you should first obtain the 1 click token
14+
# Refer to this docs: https://docs.midtrans.com/en/core-api/advanced-features?id=recurring-transaction-with-subscriptions-api
15+
16+
# You will receive saved_token_id as part of the response when the initial card payment is accepted (will also available in the HTTP notification's JSON)
17+
# Refer to this docs: https://docs.midtrans.com/en/core-api/advanced-features?id=sample-3ds-authenticate-json-response-for-the-first-transaction
18+
# {
19+
# ...
20+
# "card_type": "credit",
21+
# "saved_token_id":"481111xDUgxnnredRMAXuklkvAON1114",
22+
# "saved_token_id_expired_at": "2022-12-31 07:00:00",
23+
# ...
24+
# }
25+
# Sample saved token id for testing purpose
26+
SAVED_TOKEN_ID = '436502qFfqfAQKScMtPRPdZDOaeg7199'
27+
28+
# prepare subscription parameter ( refer to: https://api-docs.midtrans.com/#create-subscription )
29+
param = {
30+
"name": "SUBS-PY-"+datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
31+
"amount": "100000",
32+
"currency": "IDR",
33+
"payment_type": "credit_card",
34+
"token": SAVED_TOKEN_ID,
35+
"schedule": {
36+
"interval": 1,
37+
"interval_unit": "day",
38+
"max_interval": 7
39+
},
40+
"metadata": {
41+
"description": "Recurring payment for A"
42+
},
43+
"customer_details": {
44+
"first_name": "John A",
45+
"last_name": "Doe A",
46+
"email": "[email protected]",
47+
"phone": "+62812345678"
48+
}
49+
}
50+
51+
# create subscription
52+
create_subscription_response = core_api.create_subscription(param)
53+
print('create_subscription_response:')
54+
print(create_subscription_response)
55+
56+
# subscription_response is dictionary representation of API JSON response
57+
# sample:
58+
# {
59+
# 'id': 'b6eb6a04-33e6-46a2-a298-cd78e55b3a3f',
60+
# 'name': 'SUBS-PY-1',
61+
# 'amount': '100000',
62+
# 'currency': 'IDR',
63+
# 'created_at': '2021-10-27 13:29:51',
64+
# 'schedule': {
65+
# 'interval': 1,
66+
# 'current_interval': 0,
67+
# 'max_interval': 7,
68+
# 'interval_unit': 'day',
69+
# 'start_time': '2021-10-27 13:30:01',
70+
# 'next_execution_at': '2021-10-27 13:30:01'
71+
# },
72+
# 'status': 'active',
73+
# 'token': '436502qFfqfAQKScMtPRPdZDOaeg7199',
74+
# 'payment_type': 'credit_card',
75+
# 'transaction_ids': [
76+
77+
# ],
78+
# 'metadata': {
79+
# 'description': 'Recurring payment for A'
80+
# },
81+
# 'customer_details': {
82+
# 'email': '[email protected]',
83+
# 'first_name': 'John',
84+
# 'last_name': 'Doe',
85+
# 'phone': '+62812345678'
86+
# }
87+
# }
88+
89+
subscription_id_response = create_subscription_response['id']
90+
91+
# get subscription by subscription_id
92+
get_subscription_response = core_api.get_subscription(subscription_id_response)
93+
print('get_subscription_response:')
94+
print(get_subscription_response)
95+
96+
# enable subscription by subscription_id
97+
enable_subscription_response = core_api.enable_subscription(subscription_id_response)
98+
print('enable_subscription_response:')
99+
print(enable_subscription_response)
100+
101+
# update subscription by subscription_id
102+
update_param = {
103+
"name": "SUBS-PY-UPDATE",
104+
"amount": "100000",
105+
"currency": "IDR",
106+
"token": SAVED_TOKEN_ID,
107+
"schedule": {
108+
"interval": 1
109+
}
110+
}
111+
update_subscription_response = core_api.update_subscription(subscription_id_response, update_param)
112+
print('update_subscription_response:')
113+
print(update_subscription_response)
114+
115+
# disable subscription by subscription_id
116+
disable_subscription_response = core_api.disable_subscription(subscription_id_response)
117+
print('disable_subscription_response:')
118+
print(disable_subscription_response)

0 commit comments

Comments
 (0)