payu_pl 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/DOCUMENTATION_UPDATES.md +144 -0
- data/README.md +149 -0
- data/WEBHOOK_INTEGRATION_SUMMARY.md +153 -0
- data/examples/WEBHOOK_GUIDE.md +383 -0
- data/examples/rack_webhook_example.ru +66 -0
- data/examples/sinatra_webhook_example.rb +58 -0
- data/examples/webhooks_controller.rb +104 -0
- data/lib/payu_pl/configuration.rb +2 -1
- data/lib/payu_pl/version.rb +1 -1
- data/lib/payu_pl/webhooks/result.rb +32 -0
- data/lib/payu_pl/webhooks/validator.rb +236 -0
- data/lib/payu_pl.rb +3 -0
- metadata +9 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0e5d4017013c53056c374299d981c16553d6de4372f9446bd6dbb2aebbc05929
|
|
4
|
+
data.tar.gz: 22ecc4cfcf8b66c153b21956b5fa4754b70ec51589e51e8bc6703d33e2789216
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 321e0e7efebc1c9dfabf68f8a41428634f342e42e089da13198c604753d75fe45c6284bf816e648dc7ca2031a09889e7ec838ffda67bb7838c690bea1d07c49c
|
|
7
|
+
data.tar.gz: 60e13ebceb420e9a8759b741391744163e28efa1ed30211914c73509f0501d835ab2a150027496af9624fa2559037ff0ff60d9026e1d33eb938bbabd2c926a1f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-01-09
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Webhook Validation**: Complete webhook signature verification and payload parsing
|
|
8
|
+
- `PayuPl::Webhooks::Validator` - Validates PayU webhook signatures and parses JSON payloads
|
|
9
|
+
- `PayuPl::Webhooks::Result` - Success/failure result object for webhook validation
|
|
10
|
+
- Support for all PayU signature algorithms: MD5, SHA1, SHA256, SHA384, SHA512
|
|
11
|
+
- Automatic detection and verification of both MD5 concatenation variants (body+key and key+body)
|
|
12
|
+
- Framework-agnostic design (works with Rails, Sinatra, Hanami, plain Rack)
|
|
13
|
+
- Optional logging for debugging webhook processing
|
|
14
|
+
- Constant-time signature comparison for security
|
|
15
|
+
|
|
16
|
+
- **Configuration**: `PayuPl::Configuration#second_key` for webhook signature verification
|
|
17
|
+
- Three configuration methods: initializer, ENV variable, or direct parameter
|
|
18
|
+
- Automatic fallback from config → ENV → direct parameter
|
|
19
|
+
|
|
20
|
+
- **Documentation**:
|
|
21
|
+
- Comprehensive webhook integration guide (`examples/WEBHOOK_GUIDE.md`)
|
|
22
|
+
- Rails controller example (`examples/webhooks_controller.rb`)
|
|
23
|
+
- Sinatra example (`examples/sinatra_webhook_example.rb`)
|
|
24
|
+
- Rack example (`examples/rack_webhook_example.ru`)
|
|
25
|
+
- Updated README with webhook section and best practices
|
|
26
|
+
- PayU IP addresses for webhook whitelisting (production + sandbox)
|
|
27
|
+
- PayU notification retry mechanism details (20 attempts over 72 hours)
|
|
28
|
+
- Official webhook header documentation
|
|
29
|
+
- Payment status lifecycle documentation
|
|
30
|
+
|
|
31
|
+
- **Testing**: 25 comprehensive webhook tests
|
|
32
|
+
- Signature verification tests for all algorithms
|
|
33
|
+
- MD5 variant testing (both concatenation orders)
|
|
34
|
+
- Configuration priority testing
|
|
35
|
+
- Error handling and edge cases
|
|
36
|
+
- Logging behavior tests
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Amount display in logs now correctly converts from minor units to major currency units
|
|
41
|
+
- Example: `2900` (minor units) now displays as `29.00 PLN` (major units)
|
|
42
|
+
- Updated validator logs and example controllers
|
|
43
|
+
|
|
44
|
+
### Dependencies
|
|
45
|
+
|
|
46
|
+
- Added `rack ~> 3.0` to development dependencies for webhook testing
|
|
47
|
+
|
|
3
48
|
## [0.2.0] - 2025-12-31
|
|
4
49
|
|
|
5
50
|
- Add Shop Data endpoint: `GET /api/v2_1/shops/{shopId}` (`Client#retrieve_shop_data`)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Documentation Updates Based on PayU Official Documentation
|
|
2
|
+
|
|
3
|
+
## Changes Made
|
|
4
|
+
|
|
5
|
+
Based on the official PayU webhook documentation, the following enhancements have been made to ensure complete alignment with PayU's specifications.
|
|
6
|
+
|
|
7
|
+
### 1. Payment Status Clarifications
|
|
8
|
+
|
|
9
|
+
Updated status descriptions to match official definitions:
|
|
10
|
+
|
|
11
|
+
- **PENDING** - Payment is currently being processed
|
|
12
|
+
- **WAITING_FOR_CONFIRMATION** - PayU is waiting for merchant to capture payment (when auto-receive is disabled)
|
|
13
|
+
- **COMPLETED** - Payment accepted, funds will be paid out shortly
|
|
14
|
+
- **CANCELED** - Payment cancelled, buyer was not charged
|
|
15
|
+
|
|
16
|
+
### 2. Retry Mechanism Documentation
|
|
17
|
+
|
|
18
|
+
Added complete details about PayU's notification retry mechanism:
|
|
19
|
+
- PayU expects **200 HTTP status code**
|
|
20
|
+
- Up to **20 retry attempts** over 72 hours
|
|
21
|
+
- Specific retry intervals documented (1min, 2min, 5min, 10min, 30min, 1hr, etc.)
|
|
22
|
+
- Emphasis on returning 200 even if business logic fails
|
|
23
|
+
|
|
24
|
+
### 3. IP Address Whitelisting
|
|
25
|
+
|
|
26
|
+
Added official PayU IP addresses for webhook filtering:
|
|
27
|
+
|
|
28
|
+
**Production:**
|
|
29
|
+
- 185.68.12.10, 185.68.12.11, 185.68.12.12
|
|
30
|
+
- 185.68.12.26, 185.68.12.27, 185.68.12.28
|
|
31
|
+
|
|
32
|
+
**Sandbox:**
|
|
33
|
+
- 185.68.14.10, 185.68.14.11, 185.68.14.12
|
|
34
|
+
- 185.68.14.26, 185.68.14.27, 185.68.14.28
|
|
35
|
+
|
|
36
|
+
### 4. Webhook Headers Documentation
|
|
37
|
+
|
|
38
|
+
Documented all official PayU webhook headers:
|
|
39
|
+
- `OpenPayu-Signature` (also sent as `X-OpenPayU-Signature`)
|
|
40
|
+
- `Content-Type: application/json;charset=UTF-8`
|
|
41
|
+
- `Authorization` - Basic auth credentials
|
|
42
|
+
- `PayU-Processing-Time` - Processing duration in milliseconds
|
|
43
|
+
|
|
44
|
+
Added example of signature header format:
|
|
45
|
+
```
|
|
46
|
+
OpenPayu-Signature: sender=checkout;signature=...;algorithm=MD5;content=DOCUMENT
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 5. Payload Structure Details
|
|
50
|
+
|
|
51
|
+
Enhanced payload documentation with official field descriptions:
|
|
52
|
+
|
|
53
|
+
- **localReceiptDateTime** - Only present for COMPLETED status
|
|
54
|
+
- **properties[PAYMENT_ID]** - Transaction identifier (Trans ID in management panel)
|
|
55
|
+
- **payMethod.type** - Payment method indicators:
|
|
56
|
+
- `PBL` - Online/standard transfer
|
|
57
|
+
- `CARD_TOKEN` - Card payment
|
|
58
|
+
- `INSTALLMENTS` - PayU Installments
|
|
59
|
+
|
|
60
|
+
### 6. Best Practices Updates
|
|
61
|
+
|
|
62
|
+
Enhanced best practices section:
|
|
63
|
+
|
|
64
|
+
- **Duplicate Handling** - Added context about retry mechanism causing duplicates
|
|
65
|
+
- **Status Codes** - Clarified critical importance of returning 200 OK
|
|
66
|
+
- **Async Processing** - Emphasized responding quickly to avoid retries
|
|
67
|
+
- Added code examples showing correct vs incorrect patterns
|
|
68
|
+
|
|
69
|
+
### 7. Controller Example Enhancements
|
|
70
|
+
|
|
71
|
+
Updated example controller with:
|
|
72
|
+
- PayU-Processing-Time header logging for monitoring
|
|
73
|
+
- Clarified WAITING_FOR_CONFIRMATION status handling
|
|
74
|
+
- Better error handling examples
|
|
75
|
+
- More detailed status case handling
|
|
76
|
+
|
|
77
|
+
## Implementation Notes
|
|
78
|
+
|
|
79
|
+
### What Works Perfectly
|
|
80
|
+
|
|
81
|
+
✅ **Signature Verification** - Handles all PayU algorithms (MD5, SHA1, SHA256, SHA384, SHA512)
|
|
82
|
+
✅ **MD5 Variants** - Automatically checks both `MD5(body+key)` and `MD5(key+body)`
|
|
83
|
+
✅ **Header Detection** - Works with both `OpenPayu-Signature` and `X-OpenPayU-Signature`
|
|
84
|
+
✅ **Framework Agnostic** - Compatible with Rails, Sinatra, Hanami, plain Rack
|
|
85
|
+
✅ **Logging Support** - Optional detailed logging for debugging
|
|
86
|
+
✅ **Error Handling** - Clear error messages for all failure scenarios
|
|
87
|
+
|
|
88
|
+
### Developer Experience Improvements
|
|
89
|
+
|
|
90
|
+
1. **Flexible Configuration** - Three ways to set second_key (config, ENV, direct)
|
|
91
|
+
2. **Simple API** - Clean success/failure result pattern
|
|
92
|
+
3. **Comprehensive Examples** - Rails, Sinatra, Rack examples provided
|
|
93
|
+
4. **Detailed Guide** - Step-by-step integration guide with troubleshooting
|
|
94
|
+
5. **Full Test Coverage** - 25 webhook-specific tests, all passing
|
|
95
|
+
|
|
96
|
+
## Files Updated
|
|
97
|
+
|
|
98
|
+
### Documentation
|
|
99
|
+
- `examples/WEBHOOK_GUIDE.md` - Added IP addresses, retry mechanism, headers info
|
|
100
|
+
- `README.md` - Added best practices summary and IP addresses
|
|
101
|
+
- `examples/webhooks_controller.rb` - Enhanced with monitoring and better comments
|
|
102
|
+
|
|
103
|
+
### No Code Changes Required
|
|
104
|
+
|
|
105
|
+
The webhook validator implementation already correctly handles:
|
|
106
|
+
- All PayU signature algorithms
|
|
107
|
+
- Both MD5 concatenation variants
|
|
108
|
+
- Proper header parsing (signature format with semicolons)
|
|
109
|
+
- Request body preservation for multiple reads
|
|
110
|
+
- Constant-time signature comparison for security
|
|
111
|
+
|
|
112
|
+
## Verification
|
|
113
|
+
|
|
114
|
+
All tests pass (70 total, 25 webhook-specific):
|
|
115
|
+
```
|
|
116
|
+
PayuPl::Webhooks::Validator
|
|
117
|
+
✓ #initialize (4 examples)
|
|
118
|
+
✓ #verify_signature! (7 examples)
|
|
119
|
+
✓ #parse_payload (2 examples)
|
|
120
|
+
✓ #validate_and_parse (4 examples)
|
|
121
|
+
✓ logging (2 examples)
|
|
122
|
+
|
|
123
|
+
PayuPl::Webhooks::Result
|
|
124
|
+
✓ All result object behaviors (6 examples)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Next Steps for Users
|
|
128
|
+
|
|
129
|
+
When integrating webhooks, users should:
|
|
130
|
+
|
|
131
|
+
1. Get second_key from PayU merchant panel (Settings → POS Configuration)
|
|
132
|
+
2. Configure second_key in their application
|
|
133
|
+
3. Set up webhook endpoint (see examples)
|
|
134
|
+
4. Configure notifyUrl in PayU to point to their endpoint
|
|
135
|
+
5. Optional: Whitelist PayU IPs if using IP filtering
|
|
136
|
+
6. Test with PayU sandbox before production
|
|
137
|
+
7. Monitor PayU-Processing-Time header for performance insights
|
|
138
|
+
|
|
139
|
+
## References
|
|
140
|
+
|
|
141
|
+
All documentation updates are based on official PayU documentation:
|
|
142
|
+
- PayU API Reference: https://developers.payu.com/europe/api/
|
|
143
|
+
- Webhook Documentation: https://developers.payu.com/europe/docs/webhooks/
|
|
144
|
+
- Payment Lifecycle: https://developers.payu.com/europe/docs/payment-lifecycle/
|
data/README.md
CHANGED
|
@@ -112,6 +112,155 @@ client.retrieve_refund(order_id, "5000000142")
|
|
|
112
112
|
client.retrieve_transactions(order_id)
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
+
### Webhook validation
|
|
116
|
+
|
|
117
|
+
PayU sends webhook notifications when order status changes. This gem provides a validator to verify webhook signatures and parse payloads.
|
|
118
|
+
|
|
119
|
+
#### Basic usage in Rails
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
# config/routes.rb
|
|
123
|
+
post '/webhooks/payu', to: 'webhooks/payu#create'
|
|
124
|
+
|
|
125
|
+
# app/controllers/webhooks/payu_controller.rb
|
|
126
|
+
class Webhooks::PayuController < ApplicationController
|
|
127
|
+
skip_before_action :verify_authenticity_token
|
|
128
|
+
|
|
129
|
+
def create
|
|
130
|
+
result = PayuPl::Webhooks::Validator.new(request).validate_and_parse
|
|
131
|
+
|
|
132
|
+
if result.failure?
|
|
133
|
+
Rails.logger.error("PayU webhook validation failed: #{result.error}")
|
|
134
|
+
return head :bad_request
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
payload = result.data
|
|
138
|
+
order_id = payload.dig('order', 'orderId')
|
|
139
|
+
status = payload.dig('order', 'status')
|
|
140
|
+
|
|
141
|
+
# Process the webhook...
|
|
142
|
+
# (check for duplicates, enqueue background job, etc.)
|
|
143
|
+
|
|
144
|
+
head :ok
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### Configuration
|
|
150
|
+
|
|
151
|
+
Set your PayU second key (MD5 key) in one of three ways:
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
# 1. Via initializer (recommended)
|
|
155
|
+
# config/initializers/payu.rb
|
|
156
|
+
PayuPl.configure do |config|
|
|
157
|
+
config.second_key = ENV.fetch('PAYU_SECOND_KEY')
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# 2. Via ENV variable (automatic fallback)
|
|
161
|
+
ENV['PAYU_SECOND_KEY'] = 'your_second_key'
|
|
162
|
+
|
|
163
|
+
# 3. Pass directly to validator
|
|
164
|
+
validator = PayuPl::Webhooks::Validator.new(request, second_key: 'custom_key')
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### With custom logger
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
logger = Logger.new(STDOUT)
|
|
171
|
+
validator = PayuPl::Webhooks::Validator.new(request, logger: logger)
|
|
172
|
+
result = validator.validate_and_parse
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### Validation only (without parsing)
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
validator = PayuPl::Webhooks::Validator.new(request)
|
|
179
|
+
|
|
180
|
+
begin
|
|
181
|
+
validator.verify_signature!
|
|
182
|
+
# Signature is valid
|
|
183
|
+
rescue => e
|
|
184
|
+
# Signature validation failed
|
|
185
|
+
Rails.logger.error("Invalid signature: #{e.message}")
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Result object
|
|
190
|
+
|
|
191
|
+
The validator returns a `PayuPl::Webhooks::Result` object:
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
result = validator.validate_and_parse
|
|
195
|
+
|
|
196
|
+
if result.success?
|
|
197
|
+
payload = result.data
|
|
198
|
+
# Access webhook data
|
|
199
|
+
order_id = payload.dig('order', 'orderId')
|
|
200
|
+
status = payload.dig('order', 'status')
|
|
201
|
+
|
|
202
|
+
# Convert amount from minor units (2900 = 29.00 PLN)
|
|
203
|
+
total_amount = payload.dig('order', 'totalAmount').to_i / 100.0
|
|
204
|
+
currency = payload.dig('order', 'currencyCode')
|
|
205
|
+
else
|
|
206
|
+
error_message = result.error
|
|
207
|
+
# Handle validation error
|
|
208
|
+
end
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Signature algorithms
|
|
212
|
+
|
|
213
|
+
PayU supports multiple signature algorithms (MD5, SHA1, SHA256, SHA384, SHA512). The validator automatically detects the algorithm from the webhook header and verifies accordingly.
|
|
214
|
+
|
|
215
|
+
For MD5, PayU may use either `MD5(body + key)` or `MD5(key + body)`. The validator checks both variants automatically.
|
|
216
|
+
|
|
217
|
+
#### Important: Webhook Best Practices
|
|
218
|
+
|
|
219
|
+
1. **Always return 200 OK** - After signature validation, return 200 even if processing fails
|
|
220
|
+
2. **Handle duplicates** - PayU retries up to 20 times if you don't return 200
|
|
221
|
+
3. **Process asynchronously** - Store webhook and process in background job
|
|
222
|
+
4. **IP Whitelisting** (optional) - Allow PayU IPs:
|
|
223
|
+
- Production: `185.68.12.10-12`, `185.68.12.26-28`
|
|
224
|
+
- Sandbox: `185.68.14.10-12`, `185.68.14.26-28`
|
|
225
|
+
|
|
226
|
+
See `examples/WEBHOOK_GUIDE.md` for comprehensive integration guide.
|
|
227
|
+
|
|
228
|
+
#### Non-Rails frameworks
|
|
229
|
+
|
|
230
|
+
The validator works with any Rack-compatible request object:
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
# Sinatra
|
|
234
|
+
post '/webhooks/payu' do
|
|
235
|
+
result = PayuPl::Webhooks::Validator.new(request).validate_and_parse
|
|
236
|
+
|
|
237
|
+
if result.success?
|
|
238
|
+
# Process webhook
|
|
239
|
+
status 200
|
|
240
|
+
else
|
|
241
|
+
status 400
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Hanami
|
|
246
|
+
module Web::Controllers::Webhooks
|
|
247
|
+
class Payu
|
|
248
|
+
include Web::Action
|
|
249
|
+
|
|
250
|
+
def call(params)
|
|
251
|
+
result = PayuPl::Webhooks::Validator.new(request).validate_and_parse
|
|
252
|
+
|
|
253
|
+
if result.success?
|
|
254
|
+
# Process webhook
|
|
255
|
+
self.status = 200
|
|
256
|
+
else
|
|
257
|
+
self.status = 400
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
```
|
|
263
|
+
|
|
115
264
|
### Retrieve shop data
|
|
116
265
|
|
|
117
266
|
```ruby
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# PayU Webhook Integration - Summary
|
|
2
|
+
|
|
3
|
+
## What Was Added
|
|
4
|
+
|
|
5
|
+
This integration adds webhook validation capabilities to the `payu_pl` gem, allowing you to securely process PayU webhook notifications in any Ruby application.
|
|
6
|
+
|
|
7
|
+
## Files Created
|
|
8
|
+
|
|
9
|
+
### Core Library
|
|
10
|
+
- `lib/payu_pl/webhooks/result.rb` - Result object for success/failure responses
|
|
11
|
+
- `lib/payu_pl/webhooks/validator.rb` - Main webhook validator class
|
|
12
|
+
- `lib/payu_pl/configuration.rb` - Updated to support `second_key` configuration
|
|
13
|
+
|
|
14
|
+
### Tests
|
|
15
|
+
- `spec/webhooks/result_spec.rb` - Tests for Result class (6 examples)
|
|
16
|
+
- `spec/webhooks/validator_spec.rb` - Tests for Validator class (19 examples)
|
|
17
|
+
- All tests passing (70 total examples)
|
|
18
|
+
|
|
19
|
+
### Examples & Documentation
|
|
20
|
+
- `examples/WEBHOOK_GUIDE.md` - Comprehensive integration guide
|
|
21
|
+
- `examples/webhooks_controller.rb` - Rails controller example
|
|
22
|
+
- `examples/sinatra_webhook_example.rb` - Sinatra example
|
|
23
|
+
- `examples/rack_webhook_example.ru` - Plain Rack example
|
|
24
|
+
- `README.md` - Updated with webhook section
|
|
25
|
+
|
|
26
|
+
## Key Features
|
|
27
|
+
|
|
28
|
+
### 1. Flexible Configuration
|
|
29
|
+
```ruby
|
|
30
|
+
# Option 1: Via configuration
|
|
31
|
+
PayuPl.configure do |config|
|
|
32
|
+
config.second_key = ENV.fetch('PAYU_SECOND_KEY')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Option 2: Via ENV (automatic)
|
|
36
|
+
ENV['PAYU_SECOND_KEY'] = 'your_key'
|
|
37
|
+
|
|
38
|
+
# Option 3: Pass directly
|
|
39
|
+
validator = PayuPl::Webhooks::Validator.new(request, second_key: 'key')
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Framework Agnostic
|
|
43
|
+
Works with any Rack-compatible framework:
|
|
44
|
+
- Rails
|
|
45
|
+
- Sinatra
|
|
46
|
+
- Hanami
|
|
47
|
+
- Roda
|
|
48
|
+
- Plain Rack
|
|
49
|
+
|
|
50
|
+
### 3. Comprehensive Signature Validation
|
|
51
|
+
Supports all PayU signature algorithms:
|
|
52
|
+
- MD5 (with both key+body and body+key variants)
|
|
53
|
+
- SHA1, SHA256, SHA384, SHA512
|
|
54
|
+
|
|
55
|
+
### 4. Optional Logging
|
|
56
|
+
```ruby
|
|
57
|
+
validator = PayuPl::Webhooks::Validator.new(request, logger: Rails.logger)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Logs:
|
|
61
|
+
- Signature verification steps
|
|
62
|
+
- Algorithm details
|
|
63
|
+
- Payload parsing
|
|
64
|
+
- Errors and backtraces
|
|
65
|
+
|
|
66
|
+
### 5. Simple API
|
|
67
|
+
```ruby
|
|
68
|
+
result = validator.validate_and_parse
|
|
69
|
+
|
|
70
|
+
if result.success?
|
|
71
|
+
payload = result.data
|
|
72
|
+
# Process webhook...
|
|
73
|
+
else
|
|
74
|
+
error = result.error
|
|
75
|
+
# Handle error...
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Usage in Your Controller
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
class Webhooks::PayuController < ApplicationController
|
|
83
|
+
skip_before_action :verify_authenticity_token
|
|
84
|
+
|
|
85
|
+
def create
|
|
86
|
+
result = PayuPl::Webhooks::Validator.new(request).validate_and_parse
|
|
87
|
+
|
|
88
|
+
if result.failure?
|
|
89
|
+
return head :bad_request
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
payload = result.data
|
|
93
|
+
order_id = payload.dig('order', 'orderId')
|
|
94
|
+
status = payload.dig('order', 'status')
|
|
95
|
+
|
|
96
|
+
# Process webhook...
|
|
97
|
+
|
|
98
|
+
head :ok
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Security Features
|
|
104
|
+
|
|
105
|
+
1. **Constant-time signature comparison** - Prevents timing attacks
|
|
106
|
+
2. **Multi-algorithm support** - Automatic algorithm detection
|
|
107
|
+
3. **Configurable secret key** - Flexible configuration options
|
|
108
|
+
4. **Request body preservation** - Can read body multiple times
|
|
109
|
+
5. **Comprehensive error handling** - Clear error messages
|
|
110
|
+
|
|
111
|
+
## Testing
|
|
112
|
+
|
|
113
|
+
All webhook functionality is fully tested:
|
|
114
|
+
- ✅ Configuration options (ENV, config, direct)
|
|
115
|
+
- ✅ Signature verification (all algorithms)
|
|
116
|
+
- ✅ MD5 variants (body+key and key+body)
|
|
117
|
+
- ✅ Payload parsing
|
|
118
|
+
- ✅ Error handling
|
|
119
|
+
- ✅ Logging behavior
|
|
120
|
+
- ✅ Result object behavior
|
|
121
|
+
|
|
122
|
+
## Dependencies
|
|
123
|
+
|
|
124
|
+
Added to Gemfile for testing:
|
|
125
|
+
- `rack ~> 3.0` - For Rack::Request in tests
|
|
126
|
+
|
|
127
|
+
No additional runtime dependencies required.
|
|
128
|
+
|
|
129
|
+
## Next Steps
|
|
130
|
+
|
|
131
|
+
1. ✅ Webhook validation implemented
|
|
132
|
+
2. ✅ Comprehensive tests written
|
|
133
|
+
3. ✅ Documentation created
|
|
134
|
+
4. ✅ Examples provided
|
|
135
|
+
5. 🔄 Ready for use!
|
|
136
|
+
|
|
137
|
+
## Integration Checklist
|
|
138
|
+
|
|
139
|
+
For users wanting to integrate webhooks:
|
|
140
|
+
|
|
141
|
+
- [ ] Get PayU second_key from merchant panel
|
|
142
|
+
- [ ] Configure second_key (ENV or initializer)
|
|
143
|
+
- [ ] Create webhook controller/endpoint
|
|
144
|
+
- [ ] Add route for webhook
|
|
145
|
+
- [ ] Test with PayU sandbox
|
|
146
|
+
- [ ] Deploy and configure notifyUrl in PayU
|
|
147
|
+
- [ ] Monitor webhook logs
|
|
148
|
+
|
|
149
|
+
## Links
|
|
150
|
+
|
|
151
|
+
- See `examples/WEBHOOK_GUIDE.md` for detailed integration guide
|
|
152
|
+
- See `examples/webhooks_controller.rb` for Rails example
|
|
153
|
+
- See `README.md` for API documentation
|