Skip to content

Commit 96c5ab4

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 5fa0fd9 + f1db968 commit 96c5ab4

16 files changed

Lines changed: 1430 additions & 68 deletions

CHANGELOG.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file. The format
44

55
## Unreleased
66

7+
## [2.0.0][2.0.0] - 2025-09-22
8+
fix: pkg_resources deprecation warning on runtime
9+
feat: Added retry mechanism for failed API calls with `enable_retry(True)` method
10+
feat: Enhanced error handling for network connectivity issues
11+
12+
## [1.5.0][1.5.0] - 2024-12-19
13+
14+
feat: Add DeviceActivity support for POS Gateway integration
15+
16+
- Add DeviceActivity resource with create() and get_status() methods
17+
- Support PUBLIC authentication for DeviceActivity APIs
18+
- Add X-Razorpay-Device-Mode header injection for wired/wireless modes
19+
- Add DeviceMode constants (WIRED, WIRELESS)
20+
- Enhance Client to support public_auth parameter
21+
- Add comprehensive test coverage and mock responses
22+
- Fix test_multiple_client URL mismatch
23+
- Maintain backward compatibility with existing APIs
24+
25+
Endpoints:
26+
- POST /v1/devices/activity (create device activity)
27+
- GET /v1/devices/activity/{id} (get activity status)
28+
729
## [1.4.2][1.4.2] - 2024-03-19
830

931
feat: Added new API endpoints
@@ -132,7 +154,12 @@ Added Documents API (uploadAccountDoc(, fetchAccountDoc, uploadStakeholderDoc, f
132154
- Payments: List, fetch and capture payments.
133155
- Refunds: List, fetch and initiate refunds.
134156

135-
[unreleased]: https://github.com/razorpay/razorpay-python/compare/1.2.0...HEAD
157+
[unreleased]: https://github.com/razorpay/razorpay-python/compare/2.0.0...HEAD
158+
[2.0.0]: https://github.com/razorpay/razorpay-python/compare/1.5.0...2.0.0
159+
[1.5.0]: https://github.com/razorpay/razorpay-python/compare/1.4.2...1.5.0
160+
[1.4.2]: https://github.com/razorpay/razorpay-python/compare/1.4.1...1.4.2
161+
[1.4.1]: https://github.com/razorpay/razorpay-python/compare/1.3.1...1.4.1
162+
[1.3.1]: https://github.com/razorpay/razorpay-python/compare/1.3.0...1.3.1
136163
[1.2.0]: https://github.com/razorpay/razorpay-python/compare/1.1.1...1.2.0
137164
[1.1.1]: https://github.com/razorpay/razorpay-python/compare/1.1.0...1.1.1
138165
[1.1.0]: https://github.com/razorpay/razorpay-python/compare/1.0.2...1.1.0

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ keys at <https://dashboard.razorpay.com/#/app/keys>.
2525
```py
2626
import razorpay
2727
client = razorpay.Client(auth=("<YOUR_API_KEY>", "<YOUR_API_SECRET>"))
28+
29+
client.enable_retry(True) # Enable retry mechanism for failed API calls
2830
```
2931

3032
## App Details
@@ -49,6 +51,10 @@ ensure that both app title and version are strings.
4951

5052
- [Customer](documents/customer.md)
5153

54+
- [Device Activity](documents/deviceActivity.md)
55+
56+
- [POS Gateway Integration](documents/posGateway.md)
57+
5258
- [Token](documents/token.md)
5359

5460
- [Fund](documents/fund.md)

documents/deviceActivity.md

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
## Device Activity
2+
3+
### Create device activity
4+
5+
```py
6+
client.device_activity.create({
7+
"device_id": "2841158834", # Required for device_mode="wireless", optional for device_mode="wired"
8+
"action": "initiate_checkout", # Required: Action type
9+
"notes": { # Optional: Additional notes
10+
"key1": "value1",
11+
"key2": "value2"
12+
},
13+
"initiate_checkout": { # Required for initiate_checkout
14+
"name": "Acme Corp", # Optional: Business name
15+
"amount": 19900, # Required: Amount in paise (₹199.00)
16+
"currency": "INR", # Required: Currency code
17+
"description": "POS Transaction", # Required: Transaction description
18+
"type": "in_person", # Optional: Transaction type
19+
"order_id": "order_R7vqkfqG3Iw02m", # Required: Order reference
20+
"prefill": { # Optional: Customer prefill data
21+
"name": "Gaurav Kumar",
22+
"email": "gaurav.kumar@example.com",
23+
"contact": "9000090000",
24+
"method": "upi" # Optional: "upi"|"card"
25+
}
26+
}
27+
}, device_mode="wired")
28+
```
29+
30+
**Parameters:**
31+
32+
| Name | Type | Description |
33+
|---------------|--------|--------------------------------------------------------------------------------|
34+
| device_id | string | Device identifier. Required for wireless mode, optional for wired mode |
35+
| action* | string | Action type. Possible values: `initiate_checkout`, `close_checkout` |
36+
| notes | object | A key-value pair for additional information |
37+
| initiate_checkout* | object | Required when action is `initiate_checkout`. Contains checkout details |
38+
| device_mode* | string | Device communication mode. Possible values: `wired`, `wireless` |
39+
40+
**initiate_checkout Object Parameters:**
41+
42+
| Name | Type | Description |
43+
|---------------|--------|--------------------------------------------------------------------------------|
44+
| name* | string | Business name |
45+
| amount* | integer| Amount in paise (₹199.00 = 19900) |
46+
| currency* | string | Currency code (e.g., "INR") |
47+
| description* | string | Transaction description |
48+
| type | string | Optional transaction type (e.g., "in_person") |
49+
| order_id* | string | Order reference ID |
50+
| prefill | object | Optional customer prefill data (name, email, contact, method) |
51+
52+
**prefill Object Parameters:**
53+
54+
| Name | Type | Description |
55+
|---------------|--------|--------------------------------------------------------------------------------|
56+
| name | string | Optional customer name |
57+
| email | string | Optional customer email |
58+
| contact | string | Optional customer contact number |
59+
| method | string | Optional payment method: "upi", "card"
60+
61+
**Success Response:**
62+
63+
```json
64+
{
65+
"id": "pda_NVTKa9PL0yessI",
66+
"entity": "device.activity",
67+
"device_id": "2841158834",
68+
"action": "initiate_checkout",
69+
"initiate_checkout": {
70+
"name": "Acme Corp",
71+
"amount": 19900,
72+
"currency": "INR",
73+
"description": "POS Transaction",
74+
"order_id": "order_R7vqkfqG3Iw02m",
75+
"prefill": {
76+
"name": "Gaurav Kumar",
77+
"email": "gaurav.kumar@example.com",
78+
"contact": "9000090000",
79+
"method": "upi"
80+
}
81+
},
82+
"status": "processing",
83+
"error": null
84+
}
85+
```
86+
87+
**Failure Response:**
88+
89+
```json
90+
{
91+
"id": "pda_NVTKa9PL0yessI",
92+
"entity": "device.activity",
93+
"device_id": "2841158834",
94+
"action": "initiate_checkout",
95+
"initiate_checkout": {
96+
"name": "Acme Corp",
97+
"amount": 19900,
98+
"currency": "INR",
99+
"description": "POS Transaction",
100+
"order_id": "order_R7vqkfqG3Iw02m",
101+
"prefill": {
102+
"name": "Gaurav Kumar",
103+
"email": "gaurav.kumar@example.com",
104+
"contact": "9000090000",
105+
"method": "upi"
106+
}
107+
},
108+
"status": "failed",
109+
"error": {
110+
"code": "BAD_REQUEST_ERROR",
111+
"reason": "device_not_connected"
112+
}
113+
}
114+
```
115+
116+
**Status Values:**
117+
- `"processing"` - Checkout is being processed
118+
- `"completed"` - Checkout completed successfully
119+
- `"failed"` - Checkout failed with error details
120+
121+
---
122+
123+
### Create device activity (Close Checkout)
124+
125+
```py
126+
client.device_activity.create({
127+
"device_id": "2841158834",
128+
"action": "close_checkout"
129+
}, device_mode="wireless")
130+
```
131+
132+
**Parameters:**
133+
134+
| Name | Type | Description |
135+
|---------------|--------|--------------------------------------------------------------------------------|
136+
| device_id | string | Device identifier. Required for wireless mode, optional for wired mode |
137+
| action* | string | Action type: `close_checkout` |
138+
| device_mode* | string | Device communication mode. Possible values: `wired`, `wireless` |
139+
140+
**Success Response:**
141+
142+
```json
143+
{
144+
"id": "pda_NVTKa9PL0yessJ",
145+
"entity": "device.activity",
146+
"device_id": "2841158834",
147+
"action": "close_checkout",
148+
"status": "completed",
149+
"error": null
150+
}
151+
```
152+
153+
**Failure Response:**
154+
155+
```json
156+
{
157+
"id": "pda_NVTKa9PL0yessJ",
158+
"entity": "device.activity",
159+
"device_id": "2841158834",
160+
"action": "close_checkout",
161+
"status": "failed",
162+
"error": {
163+
"code": "BAD_REQUEST_ERROR",
164+
"reason": "checkout_not_found"
165+
}
166+
}
167+
```
168+
---
169+
170+
## Device Modes
171+
172+
### Wired Mode
173+
- **device_mode**: `"wired"`
174+
- **device_id**: Optional
175+
- Direct device connection
176+
177+
### Wireless Mode
178+
- **device_mode**: `"wireless"`
179+
- **device_id**: Required
180+
- Wireless device communication
181+
182+
---
183+
184+
## Error Handling
185+
186+
```py
187+
from razorpay.errors import BadRequestError
188+
189+
try:
190+
response = client.device_activity.create({
191+
"device_id": "2841158834",
192+
"action": "initiate_checkout"
193+
}, device_mode="invalid_mode")
194+
except BadRequestError as e:
195+
print(f"Error: {e}")
196+
# Output: Invalid device mode. Allowed values are 'wired' and 'wireless'.
197+
```
198+
199+
**Common Errors:**
200+
201+
| Error | Description | Solution |
202+
|-------|-------------|----------|
203+
| `BadRequestError` | Invalid device_mode parameter | Use only `"wired"` or `"wireless"` |
204+
| `BadRequestError` | Missing device_id in wireless mode | Include device_id when using wireless mode |
205+
206+
**API Error Responses:**
207+
208+
| Error Code | Reason | Description | Solution |
209+
|------------|--------|-------------|----------|
210+
| `BAD_REQUEST_ERROR` | `device_not_connected` | Device is not connected | Check device connection and try again |
211+
| `BAD_REQUEST_ERROR` | `checkout_not_found` | Checkout session not found | Verify checkout was initiated before closing |
212+
213+
---
214+
215+
## Example Usage
216+
217+
```py
218+
import razorpay
219+
220+
# Initialize client
221+
client = razorpay.Client(auth=('key_id', 'key_secret'), base_url='http://localhost:PORT')
222+
223+
try:
224+
# Step 1: Initiate checkout
225+
activity = client.device_activity.create({
226+
"device_id": "2841158834",
227+
"action": "initiate_checkout",
228+
"notes": {"merchant_id": "12345"},
229+
"initiate_checkout": {
230+
"name": "Acme Corp",
231+
"amount": 19900,
232+
"currency": "INR",
233+
"description": "POS Transaction",
234+
"type": "in_person", # Optional
235+
"order_id": "order_R7vqkfqG3Iw02m",
236+
"prefill": {
237+
"name": "Gaurav Kumar",
238+
"email": "gaurav.kumar@example.com",
239+
"contact": "9000090000",
240+
"method": "upi"
241+
}
242+
}
243+
}, device_mode="wired")
244+
245+
activity_id = activity['id']
246+
print(f"Checkout initiated: {activity_id}")
247+
248+
# Step 2: Close checkout when done
249+
close_response = client.device_activity.create({
250+
"device_id": "2841158834",
251+
"action": "close_checkout"
252+
}, device_mode="wired")
253+
254+
print("Checkout closed successfully")
255+
256+
except Exception as e:
257+
print(f"Error: {e}")
258+
```
259+
260+
---
261+
262+
## Integration with Order APIs
263+
264+
Device Activity APIs work seamlessly with Order APIs for complete POS integration:
265+
266+
```py
267+
# Create order with device_mode
268+
order = client.order.create({
269+
"amount": 50000,
270+
"currency": "INR",
271+
"receipt": "order_001"
272+
}, device_mode="wired")
273+
274+
# Initiate device checkout
275+
checkout = client.device_activity.create({
276+
"device_id": "2841158834",
277+
"action": "initiate_checkout",
278+
"notes": {"order_id": order['id']},
279+
"initiate_checkout": {
280+
"name": "Acme Corp",
281+
"amount": order['amount'],
282+
"currency": order['currency'],
283+
"description": "POS Transaction",
284+
"type": "in_person",
285+
"order_id": order['id'],
286+
"prefill": {
287+
"method": "upi"
288+
}
289+
}
290+
}, device_mode="wired")
291+
292+
```

0 commit comments

Comments
 (0)