voucherify 0.8.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,16 +1,47 @@
1
- ## Voucherify Ruby SDK
2
-
3
- [Voucherify](http://voucherify.io?utm_source=github&utm_medium=sdk&utm_campaign=acq) is an API-first platform for software developers who are dissatisfied with high-maintenance custom coupon software. Our product is a coupon infrastructure through API that provides a quicker way to build coupon generation, distribution and tracking. Unlike legacy coupon software we have:
4
-
5
- * an API-first SaaS platform that enables customisation of every aspect of coupon campaigns
6
- * a management console that helps cut down maintenance and reporting overhead
7
- * an infrastructure to scale up coupon activity in no time
8
-
9
- Full documentation is located at [voucherify.readme.io](https://voucherify.readme.io).
10
-
11
- ### Usage
12
-
13
- #### Installation
1
+ <p align="center">
2
+ <img src="./voucherify-ruby-sdk.png"/>
3
+ </p>
4
+
5
+ <h3 align="center">Official <a href="http://voucherify.io?utm_source=github&utm_medium=sdk&utm_campaign=acq">Voucherify</a> SDK for Ruby</h3>
6
+
7
+ <p align="center">
8
+ <a href="https://rubygems.org/gems/voucherify"><img src="https://img.shields.io/gem/v/voucherify.svg" alt="Gem Version"/></a>
9
+ <a href="https://rubygems.org/gems/voucherify"><img src="https://img.shields.io/gem/dt/voucherify.svg" alt="Gem Downloads"/></a>
10
+ </p>
11
+ <hr />
12
+
13
+ <p align="center">
14
+ <b><a href="#migration-from-0-x">Migration from 0.x</a></b>
15
+ |
16
+ <b><a href="#setup">Setup</a></b>
17
+ |
18
+ <b><a href="#error-handling">Error handling</a></b>
19
+ |
20
+ <b><a href="#development">Development</a></b>
21
+ |
22
+ <b><a href="#contributing">Contributing</a></b>
23
+ |
24
+ <b><a href="#changelog">Changelog</a></b>
25
+ </p>
26
+
27
+ <p align="center">
28
+ API:
29
+ <a href="#vouchers-api">Vouchers</a>
30
+ |
31
+ <a href="#distributions-api">Distributions</a>
32
+ |
33
+ <a href="#validations-api">Validations</a>
34
+ |
35
+ <a href="#redemptions-api">Redemptions</a>
36
+ |
37
+ <a href="#customers-api">Customers</a>
38
+ |
39
+ <a href="#utils">Utils</a>
40
+ </p>
41
+
42
+ ---
43
+
44
+ ## Setup
14
45
 
15
46
  Add this line to your application's Gemfile:
16
47
 
@@ -26,870 +57,217 @@ Or install it yourself as:
26
57
 
27
58
  $ gem install voucherify
28
59
 
29
- #### Authentication
30
-
31
- [Log-in](http://app.voucherify.io/#/login) to Voucherify web interface and obtain your Application Keys from [Configuration](https://app.voucherify.io/#/app/configuration):
32
-
33
- ![](https://www.filepicker.io/api/file/WKYkl2bSAWKHccEN9tEG)
60
+ [Log-in](http://app.voucherify.io/?utm_source=github&utm_medium=sdk&utm_campaign=acq#/login) to Voucherify web interface and obtain your Application Keys from [Configuration](https://app.voucherify.io/?utm_source=github&utm_medium=sdk&utm_campaign=acq#/app/configuration):
34
61
 
35
62
  ```ruby
36
- require "voucherify"
63
+ require 'voucherify'
37
64
 
38
- voucherify = Voucherify.new({
39
- "applicationId" => "YOUR-APPLICATION-ID-OBTAINED-FROM-CONFIGURATION",
40
- "clientSecretKey" => "YOUR-CLIENT-SECRET-KEY-OBTAINED-FROM-CONFIGURATION"
65
+ voucherify = Voucherify::Client.new({
66
+ :applicationId => 'YOUR-APPLICATION-ID',
67
+ :clientSecretKey => 'YOUR-CLIENT-SECRET-KEY'
41
68
  })
42
69
  ```
43
70
 
44
- #### Error handling
45
-
46
- This voucherify gem uses [rest-client](https://github.com/rest-client/rest-client) under the hood for handling HTTP calls. In case of an HTTP 4xx or 5xx error, a RestClient exception is thrown. The server's specific response is available in `.response` of the exception object.
47
-
48
- ```ruby
49
- begin
50
- voucherify.publish("test")
51
- rescue => e
52
- JSON.parse(e.response)
53
- end
54
- ```
55
-
56
- ```json
57
- {
58
- "code": 400,
59
- "message": "Couldn't find any voucher suitable for publication."
60
- }
61
- ```
62
-
63
- Please refer to [rest-client documentation](https://github.com/rest-client/rest-client#exceptions-see-httpwwww3orgprotocolsrfc2616rfc2616-sec10html) for more detailed information.
64
-
65
- #### Listing vouchers
71
+ ## API
66
72
 
67
- Use `voucherify.vouchers(filter)` to get a filtered list of vouchers.
73
+ This SDK is fully consistent with restful API Voucherify provides.
74
+ Detailed descriptions and example responses you will find at [official docs](https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq).
75
+ Method headers point to more detailed params description you can use.
68
76
 
69
- Filter paramters
70
- - code_query
71
- - limit (default 10)
72
- - skip (default 0)
73
- - category
74
- - campaign
75
- - customer
76
-
77
- Example:
77
+ ### Vouchers API
78
+ Methods are provided within `voucherify.vouchers.*` namespace.
79
+ - [Create Voucher](#create-voucher)
80
+ - [Get Voucher](#get-voucher)
81
+ - [Update Voucher](#update-voucher)
82
+ - [Delete Voucher](#delete-voucher)
83
+ - [List Vouchers](#list-vouchers)
84
+ - [Enable Voucher](#enable-voucher)
85
+ - [Disable Voucher](#disable-voucher)
78
86
 
87
+ #### [Create Voucher]
79
88
  ```ruby
80
- voucherify.list({ limit: 10, skip: 20, category: "API Test" })
81
- ```
82
-
83
- Result:
84
- ```json
85
- [{
86
- "code": "9mYBpIk",
87
- "campaign": null,
88
- "category": "API Test",
89
- "type": "DISCOUNT_VOUCHER",
90
- "discount": {
91
- "type": "AMOUNT",
92
- "amount_off": 400
93
- },
94
- "start_date": "2016-03-01T12:00:00Z",
95
- "expiration_date": null,
96
- "publish": {
97
- "object": "list",
98
- "count": 1,
99
- "data_ref": "entries",
100
- "entries": [{
101
- "channel": "Email",
102
- "customer": "alice.morgan@email.com",
103
- "customer_id": "cust_1fnSUBno3iimKTPNDCkjg4xV",
104
- "published_at": "2016-01-22T09:25:07Z"
105
- }]
106
- },
107
- "redemption": {
108
- "object": "list",
109
- "quantity": 3,
110
- "data_ref": "redemption_entries",
111
- "redeemed_quantity": 1,
112
- "redemption_entries": [{
113
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
114
- "object": "redemption",
115
- "date": "2016-04-24T06:03:35Z",
116
- "customer_id": null,
117
- "tracking_id": "(tracking_id not set)"
118
- }]
119
- },
120
- "active": true,
121
- "additional_info": null,
122
- "metadata": null
123
- }, {
124
- "code": "AzTsIH",
125
- "campaign": null,
126
- "category": "API Test",
127
- "type": "GIFT_VOUCHER",
128
- "gift": {
129
- "amount": 10000,
130
- "balance": 5000
131
- },
132
- "start_date": "2016-03-01T10:00:00Z",
133
- "expiration_date": null,
134
- "publish": {
135
- "object": "list",
136
- "count": 1,
137
- "data_ref": "entries",
138
- "entries": [{
139
- "channel": "Email",
140
- "customer": "alice.morgan@email.com",
141
- "customer_id": "cust_1fnSUBno3iimKTPNDCkjg4xV",
142
- "published_at": "2016-01-22T09:25:07Z"
143
- }]
144
- },
145
- "redemption": {
146
- "object": "list",
147
- "quantity": 0,
148
- "data_ref": "redemption_entries",
149
- "redeemed_quantity": 0,
150
- "redeemed_amount": 0,
151
- "redemption_entries": []
152
- },
153
- "active": true,
154
- "additional_info": null,
155
- "metadata": null
156
- }]
89
+ voucherify.vouchers.create(code, options)
157
90
  ```
158
-
159
- #### Getting voucher details
160
-
91
+ Check [voucher object](https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#the-voucher-object).
92
+ #### [Get Voucher]
161
93
  ```ruby
162
- voucherify.get("v1GiJYuuS")
94
+ voucherify.vouchers.get(code)
163
95
  ```
164
-
165
- Result:
166
- ```json
167
- {
168
- "code": "v1GiJYuuS",
169
- "campaign": "vip",
170
- "type": "DISCOUNT_VOUCHER",
171
- "discount": {
172
- "percent_off": 10.0,
173
- "type": "PERCENT"
174
- },
175
- "expiration_date": "2016-12-31T23:59:59Z",
176
- "publish": {
177
- "object": "list",
178
- "count": 1,
179
- "data_ref": "entries",
180
- "entries": [{
181
- "channel": "Email",
182
- "customer": "alice.morgan@email.com",
183
- "customer_id": "cust_1fnSUBno3iimKTPNDCkjg4xV",
184
- "published_at": "2016-01-22T09:25:07Z"
185
- }]
186
- },
187
- "redemption": {
188
- "object": "list",
189
- "quantity": 3,
190
- "data_ref": "redemption_entries",
191
- "redeemed_quantity": 1,
192
- "redemption_entries": [
193
- {
194
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
195
- "object": "redemption",
196
- "date": "2016-04-24T06:03:35Z",
197
- "customer_id": null,
198
- "tracking_id": "(tracking_id not set)"
199
- }
200
- ]
201
- },
202
- "additional_info": ""
203
- }
204
- ```
205
-
206
- #### Getting voucher redemption
207
-
96
+ #### [Update Voucher]
208
97
  ```ruby
209
- voucherify.redemption("v1GiJYuuS")
98
+ voucherify.vouchers.update(voucher)
210
99
  ```
211
-
212
- Result:
213
- ```json
214
- {
215
- "quantity": 3,
216
- "redeemed_quantity": 1,
217
- "redemption_entries": [
218
- {
219
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
220
- "object": "redemption",
221
- "date": "2016-04-24T06:03:35Z",
222
- "customer_id": null,
223
- "tracking_id": "(tracking_id not set)"
224
- }
225
- ]
226
- }
227
- ```
228
-
229
- #### Publishing voucher
230
-
231
- This method selects a voucher that is suitable for publication, adds a publish entry and returns the voucher.
232
- A voucher is suitable for publication when it's active and hasn't been published more times than the redemption limit.
233
-
234
- Example:
235
-
100
+ #### [Delete Voucher]
236
101
  ```ruby
237
- voucherify.publish("First Ride")
102
+ voucherify.vouchers.delete(code, [params])
238
103
  ```
239
-
240
- or
241
-
104
+ #### [List Vouchers]
242
105
  ```ruby
243
- voucherify.publish({campaign: "First Ride", channel: "Email", customer: "donny.roll@mail.com"})
106
+ voucherify.vouchers.list
244
107
  ```
245
-
246
- or
247
-
108
+ #### [Enable Voucher]
248
109
  ```ruby
249
- voucherify.publish({voucher: "FR-zT-u9I7zG", channel: "Email", customer: "donny.roll@mail.com"})
250
- ```
251
-
252
- Positive result:
253
-
254
- ```json
255
- {
256
- "code": "FR-zT-u9I7zG",
257
- "campaign": "First Ride",
258
- "category": null,
259
- "discount": {
260
- "type": "PERCENT",
261
- "amount_off": 50
262
- },
263
- "start_date": "2015-01-01T00:00:00Z",
264
- "expiration_date": "2016-12-31T23:59:59Z",
265
- "publish": {
266
- "object": "list",
267
- "count": 1,
268
- "data_ref": "entries",
269
- "entries": [{
270
- "channel": "Email",
271
- "customer": "donny.roll@mail.com",
272
- "customer_id": "cust_1fnSUBno3iimKTPNDCkjg4xV",
273
- "published_at": "2016-01-22T09:25:07Z"
274
- }]
275
- },
276
- "redemption": {
277
- "object": "list",
278
- "quantity": 0,
279
- "data_ref": "redemption_entries",
280
- "redeemed_quantity": 0,
281
- "redemption_entries": []
282
- },
283
- "active": true,
284
- "additional_info": null
285
- }
286
- ```
287
-
288
- Possible error:
289
-
290
- ```json
291
- {
292
- "code": 400,
293
- "message": "Couldn't find any voucher suitable for publication."
294
- }
110
+ voucherify.vouchers.enable(code)
295
111
  ```
296
-
297
- #### Validating vouchers
298
-
299
- Validation lets you check if given voucher code can be successfuly redeemed.
300
-
301
- `voucherify.validate(code, context)`
302
-
303
- The `context` param is generally optional unless you are validating a gift voucher or a voucher with order validation rules.
304
- Then you have to pass `order.amount` expressed in cents (e.g. $10 is 1000).
305
- Validation rules also require to pass `order.items` as a list of objects including `product_id`, `sku_id` and `quantity`.
306
-
307
- Example:
308
-
309
- ```
310
- validation_result = voucherify.validate("91Ft4U", {
311
- tracking_id: "john@lemon.com",
312
- customer: {
313
- id: "cust_07sVjVsr71Ewot9lVZSrIVLH",
314
- source_id: "john@lemon.com",
315
- name: "John Lemon"
316
- },
317
- order: {
318
- amount: 1250
319
- items: [
320
- { product_id: "prod_ELvEXqF4qzB7Rs", sku_id: "sku_GoXSOI4FwJZafb", quantity: 1 },
321
- { product_id: "prod_wye1naw5JO5dh3", sku_id: "sku_U3rHSlfOCGUnbo", quantity: 2 }
322
- ]
323
- }
324
- })
325
- ```
326
-
327
- Successful validation result:
328
- ```
329
- {"code"=>"91Ft4U", "valid"=>true, "gift"=>{"amount"=>10000, "balance"=>5000}, "tracking_id"=>"john@lemon.com"}
330
- ```
331
-
332
- Failed validation result:
333
- ```
334
- {"code"=>"91Ft4U", "valid"=>false, "reason"=>"gift amount exceeded", "tracking_id"=>"john@lemon.com"}
335
- ```
336
-
337
- There are several reasons why validation may fail (`valid: false` response). You can find the actual cause in the `reason` field:
338
-
339
- - `voucher not found`
340
- - `voucher is disabled`
341
- - `voucher not active yet`
342
- - `voucher expired`
343
- - `quantity exceeded`
344
- - `gift amount exceeded`
345
- - `customer does not match segment rules`
346
- - `order does not match validation rules`
347
-
348
- #### Redeeming voucher
349
-
350
- ##### 1. Just by code
351
-
112
+ #### [Disable Voucher]
352
113
  ```ruby
353
- voucherify.redeem("v1GiJYuuS")
114
+ voucherify.vouchers.disable(code)
354
115
  ```
116
+ ---
355
117
 
356
- Result (voucher details after redemption):
118
+ ### Distributions API
119
+ Methods are provided within `voucherify.distributions.*` namespace.
357
120
 
358
- ```json
359
- {
360
- "id": "r_yRmanaA6EgSE9uDYvMQ5Evfp",
361
- "object": "redemption",
362
- "date": "2016-04-25T10:34:57Z",
363
- "customer_id": null,
364
- "tracking_id": "(tracking_id not set)",
365
- "voucher": {
366
- "code": "v1GiJYuuS",
367
- "campaign": "vip",
368
- "type": "DISCOUNT_VOUCHER",
369
- "discount": {
370
- "percent_off": 10.0,
371
- "type": "PERCENT"
372
- },
373
- "expiration_date": "2016-12-31T23:59:59Z",
374
- "redemption": {
375
- "object": "list",
376
- "quantity": 3,
377
- "data_ref": "redemption_entries",
378
- "redeemed_quantity": 2,
379
- "redemption_entries": [
380
- {
381
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
382
- "object": "redemption",
383
- "date": "2016-04-24T06:03:35Z",
384
- "customer_id": null,
385
- "tracking_id": "(tracking_id not set)"
386
- },
387
- {
388
- "id": "r_yRmanaA6EgSE9uDYvMQ5Evfp",
389
- "object": "redemption",
390
- "date": "2016-04-25T10:34:57Z",
391
- "customer_id": null,
392
- "tracking_id": "(tracking_id not set)"
393
- }
394
- ]
395
- },
396
- "active": true,
397
- "additional_info": ""
398
- }
399
- }
400
- ```
401
-
402
- Error:
403
- ```json
404
- {
405
- "code": 400,
406
- "message": "voucher expired or quantity exceeded",
407
- "details": "v1GiJYuuS"
408
- }
409
- ```
410
-
411
- ##### 2. With tracking id
412
-
413
- You can provide a tracking id (e.g. your customer's login or a generated id) to the voucher redemption request.
121
+ - [Publish Vouchers](#publish-vouchers)
414
122
 
123
+ #### [Publish Vouchers]
415
124
  ```ruby
416
- voucherify.redeem("v1GiJYuuS", "alice.morgan")
125
+ voucherify.distributions.publish(campaign_name)
417
126
  ```
418
127
 
419
- Result:
420
- ```json
421
- {
422
- "id": "r_yRmanaA6EgSE9uDYvMQ5Evfp",
423
- "object": "redemption",
424
- "date": "2016-04-25T10:34:57Z",
425
- "customer_id": "cust_84LPwcHJ1jVEpxV1uF9nLLBB",
426
- "tracking_id": "alice.morgan",
427
- "voucher": {
428
- "code": "v1GiJYuuS",
429
- "campaign": "vip",
430
- "type": "DISCOUNT_VOUCHER",
431
- "discount": {
432
- "percent_off": 10.0,
433
- "type": "PERCENT"
434
- },
435
- "expiration_date": "2016-12-31T23:59:59Z",
436
- "redemption": {
437
- "quantity": 3,
438
- "redeemed_quantity": 3,
439
- "redemption_entries": [
440
- {
441
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
442
- "object": "redemption",
443
- "date": "2016-04-24T06:03:35Z",
444
- "customer_id": null,
445
- "tracking_id": "(tracking_id not set)"
446
- },
447
- {
448
- "id": "r_yRmanaA6EgSE9uDYvMQ5Evfp",
449
- "object": "redemption",
450
- "date": "2016-04-25T10:34:57Z",
451
- "customer_id": null,
452
- "tracking_id": "(tracking_id not set)"
453
- },
454
- {
455
- "id": "r_irOQWUTAjthQwnkn5JQM1V6N",
456
- "object": "redemption",
457
- "date": "2016-04-25T12:04:08Z",
458
- "customer_id": "cust_84LPwcHJ1jVEpxV1uF9nLLBB",
459
- "tracking_id": "alice.morgan"
460
- }
461
- ]
462
- },
463
- "active": true,
464
- "additional_info": ""
465
- }
466
- }
467
- ```
128
+ ---
468
129
 
469
- ##### 3. With customer profile
130
+ ### Validations API
131
+ Methods are provided within `voucherify.validations.*` namespace.
470
132
 
471
- You can record a detailed customer profile consisting of an `source_id`, `name`, `email`, `description` and a `metadata` section that can include any data you wish. Voucherify will create (or update) provided customer profile in its database.
133
+ - [Validate Voucher](#validate-voucher)
472
134
 
135
+ #### [Validate Voucher]
473
136
  ```ruby
474
- voucherify.redeem({
475
- "voucher" => "v1GiJYuuS",
476
- "customer" => {
477
- "source_id" => "alice.morgan",
478
- "name" => "Alice Morgan",
479
- "email" => "alice@morgan.com",
480
- "description" => "look ma no hands",
481
- "metadata" => {
482
- "locale" => "en-GB",
483
- "shoeSize" => 36.6
484
- }
485
- }
486
- })
137
+ voucherify.validations.validate_voucher(code, [context])
487
138
  ```
488
139
 
489
- ##### 4. With customer id
140
+ ---
490
141
 
491
- If you already created a customer profile in Voucherify's database, whether it was implicitly by providing it to the `redeem` function or explicitly by invoking the [`customer.create`](#create-customer) method, you can identify your customer in following redemptions by a generated id (starting with `cust_`).
142
+ ### Redemptions API
143
+ Methods are provided within `voucherify.redemptions.*` namespace.
492
144
 
493
- ```ruby
494
- voucherify.redeem({
495
- "voucher" => "v1GiJYuuS",
496
- "customer" => {
497
- "id" => "cust_C9qJ3xKgZFqkpMw7b21MF2ow"
498
- })
499
- ```
500
-
501
- ##### 5. With order amount
502
-
503
- Redeeming a gift voucher requires passing order amount. The same applies to vouchers with validation rules on order's total amount.
504
- Order amount have to be expressed in cents, as an integer. For example $22.50 should be provided as 2250.
505
- Gift voucher balance will be used to cover the order amount entirely or partially.
145
+ - [Redeem Voucher](#redeem-voucher)
146
+ - [List Redemptions](#list-redemptions)
147
+ - [Get Voucher's Redemptions](#get-vouchers-redemptions)
148
+ - [Rollback Redemption](#rollback-redemption)
506
149
 
150
+ #### [Redeem Voucher]
507
151
  ```ruby
508
- voucherify.redeem({
509
- "voucher" => "91Ft4U",
510
- "order" => {
511
- "amount" => 2250
512
- })
513
- ```
514
-
515
- ##### 6. With order items
152
+ voucherify.redemptions.redeem(code, [params])
516
153
 
517
- Vouchers with validation rules regarding products or SKUs require to pass `order.items`.
518
- Items are a list of objects consisting of `product_id`, `sku_id` and `quantity`.
519
-
520
- ```javascript
521
- voucherify.redeem({
522
- voucher: "91Ft4U",
523
- order: {
524
- items: [
525
- { product_id: "prod_ELvEXqF4qzB7Rs", sku_id: "sku_GoXSOI4FwJZafb", quantity: 1 },
526
- { product_id: "prod_wye1naw5JO5dh3", sku_id: "sku_U3rHSlfOCGUnbo", quantity: 2 }
527
- ]
528
- })
154
+ // Removed!
155
+ voucherify.redemptions.redeem(code, tracking_id) // use: voucherify.redemptions.redeem(code, {:customer => {:source_id => 'source_id'}})
529
156
  ```
530
-
531
- #### Listing redemptions
532
-
533
- Use `voucherify.redemptions(filter)` to get a filtered list of redemptions.
534
- Filter parameters:
535
-
536
- - limit (default: 100)
537
- - page (default: 0)
538
- - start_date (default: beginning of current month)
539
- - end_date (default: end of current month)
540
- - result - Success | Failure-NotExist | Failure-Inactive
541
- - customer - id or source_id
542
-
543
-
544
- Example - 1000 successful redemptions from April 2016:
545
-
157
+ #### [List Redemptions]
546
158
  ```ruby
547
- filter = {
548
- limit: 1000,
549
- page: 0,
550
- start_date: "2016-04-01T00:00:00",
551
- end_date: "2016-04-30T23:59:59",
552
- result: "Success"
553
- }
554
-
555
- voucherify.redemptions(filter)
159
+ voucherify.redemptions.list
160
+ voucherify.redemptions.list(params)
556
161
  ```
557
-
558
- #### Creating vouchers
559
-
560
- Use `voucherify.create(code, options)` to create new vouchers.
561
-
562
- You can specify voucher's code in the first parameter or pass `nil` to let Voucherify generate one.
563
- By default a generated code is a 8 characters long alphanumeric string, however,
564
- you can define how to create the random code passing a `code_config` hash:
565
- - `length` - Number of characters in a generated code (excluding prefix and postfix).
566
- - `charset` - Characters that can appear in the code.
567
- - `prefix` - A text appended before the code.
568
- - `postfix` - A text appended after the code.
569
- - `pattern` - A pattern for codes where hashes (#) will be replaced with random characters. Overrides `length`.
570
-
162
+ #### [Get Voucher's Redemptions]
571
163
  ```ruby
572
- code = "EASTER-2016" # use given voucher code
573
- code = nil # for an automatically generated string
574
-
575
- # single-use voucher with 10% off discount that is valid throughout the whole 2016
576
- opts = {
577
- code_config: {
578
- charset: "0123456789",
579
- pattern: "TEST-#####"
580
- },
581
- category: "New Customers",
582
- type: "DISCOUNT_VOUCHER",
583
- discount: {
584
- percent_off: 10.0,
585
- type: "PERCENT"
586
- },
587
- start_date: "2016-01-01T00:00:00Z",
588
- expiration_date: "2016-12-31T23:59:59Z",
589
- redemption: {
590
- quantity: 1
591
- }
592
- }
593
-
594
- voucherify.create(code, opts)
164
+ voucherify.redemptions.get_for_voucher(code)
595
165
  ```
596
-
597
- Result (voucher details):
598
- ```json
599
- {
600
- "code": "9Yi5g",
601
- "campaign": null,
602
- "category": "New Customers",
603
- "type": "DISCOUNT_VOUCHER",
604
- "discount": {
605
- "type": "PERCENT",
606
- "percent_off": 10.0
607
- },
608
- "start_date": "2016-01-01T00:00:00Z",
609
- "expiration_date": "2016-12-31T23:59:59Z",
610
- "publish": {
611
- "object": "list",
612
- "count": 0,
613
- "data_ref": "entries",
614
- "entries": []
615
- },
616
- "redemption": {
617
- "object": "list",
618
- "quantity": 1,
619
- "data_ref": "redemption_entries",
620
- "redeemed_quantity": 0,
621
- "redemption_entries": []
622
- },
623
- "active": true,
624
- "additional_info": null,
625
- "metadata": null
626
- }
627
- ```
628
-
629
- #### Updating vouchers
630
-
631
- You can change some properties of a voucher that has been already created:
632
- - category
633
- - start date
634
- - expiration date
635
- - active
636
- - additinal info
637
- - metadata
638
-
639
- Other fields than listed above won't be modified. Even if provided they will be silently skipped.
640
-
641
- Use `voucherify.update(voucher_update)` to update a voucher.
642
-
166
+ #### [Rollback Redemption]
643
167
  ```ruby
644
- voucher_update = {
645
- "code" => "Summer-2016",
646
- "category" => "Season",
647
- "start_date" => "2016-07-01T00:00:00Z",
648
- "expiration_date" => "2016-08-31T23:59:59Z",
649
- }
168
+ voucherify.redemptions.rollback(redemption_id, [params])
650
169
 
651
- updated_voucher = voucherify.update(voucher_update)
170
+ // Removed!
171
+ voucherify.redemptions.rollback(code, tracking_id, reason) // use: voucherify.redemptions.rollback(code, {:customer => {:source_id => 'source_id'}, :reason => 'reason'})
652
172
  ```
173
+ Check [redemption rollback object](https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#the-redemption-rollback-object).
653
174
 
654
- #### Disabling a voucher
655
-
656
- ```ruby
657
- voucherify.disable("EASTER-2016")
658
- ```
175
+ ---
659
176
 
660
- The response has empty body.
177
+ ### Customers API
178
+ Methods are provided within `voucherify.customers.*` namespace.
661
179
 
662
- #### Enabling a voucher
180
+ - [Create Customer](#create-customer)
181
+ - [Get Customer](#get-customer)
182
+ - [Update Customer](#update-customer)
183
+ - [Delete Customer](#delete-customer)
663
184
 
185
+ #### [Create Customer]
664
186
  ```ruby
665
- voucherify.enable("EASTER-2016")
187
+ voucherify.customers.create(customer)
666
188
  ```
667
-
668
- The response has empty body.
669
-
670
- #### Rollback redemption
671
-
672
- You can revert a redemption by calling `voucherify.rollback(redemption_id, tracking_id*, reason*, callback*)`.
673
- This operation creates a rollback entry in voucher's redemption history (`redemption.redemption_entries`)
674
- and gives 1 redemption back to the pool (decreases `redeemed_quantity` by 1).
675
-
189
+ Check [customer object](https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#the-customer-object).
190
+ #### [Get Customer]
676
191
  ```ruby
677
- voucherify.rollback("r_irOQWUTAjthQwnkn5JQM1V6N", "alice.morgan")
678
- ```
679
-
680
- Result:
192
+ voucherify.customers.get(customer_id)
681
193
  ```
682
- {
683
- "id": "rr_1634wLkb8glgRXrTmsxRzDBd",
684
- "object": "redemption_rollback",
685
- "date": "2016-04-25T10:35:02Z",
686
- "customer_id": "cust_84LPwcHJ1jVEpxV1uF9nLLBB",
687
- "tracking_id": "alice.morgan",
688
- "redemption": "r_irOQWUTAjthQwnkn5JQM1V6N",
689
- "voucher": {
690
- "code": "v1GiJYuuS",
691
- "campaign": "vip",
692
- "discount": {
693
- "percent_off": 10.0,
694
- "type": "PERCENT"
695
- },
696
- "expiration_date": "2016-12-31T23:59:59Z",
697
- "publish": {
698
- "object": "list",
699
- "count": 0,
700
- "data_ref": "entries",
701
- "entries": []
702
- },
703
- "redemption": {
704
- "object": "list",
705
- "quantity": 3,
706
- "data_ref": "redemption_entries",
707
- "redeemed_quantity": 2,
708
- "redemption_entries": [
709
- {
710
- "id": "r_gQzOnTwmhn2nTLwW4sZslNKY",
711
- "object": "redemption",
712
- "date": "2016-04-24T06:03:35Z",
713
- "customer_id": null,
714
- "tracking_id": "(tracking_id not set)"
715
- },
716
- {
717
- "id": "r_yRmanaA6EgSE9uDYvMQ5Evfp",
718
- "object": "redemption",
719
- "date": "2016-04-25T10:34:57Z",
720
- "customer_id": null,
721
- "tracking_id": "(tracking_id not set)"
722
- },
723
- {
724
- "id": "r_irOQWUTAjthQwnkn5JQM1V6N",
725
- "object": "redemption",
726
- "date": "2016-04-25T12:04:08Z",
727
- "customer_id": "cust_84LPwcHJ1jVEpxV1uF9nLLBB",
728
- "tracking_id": "alice.morgan"
729
- },
730
- {
731
- "id": "rr_1634wLkb8glgRXrTmsxRzDBd",
732
- "object": "redemption_rollback",
733
- "date": "2016-04-25T10:35:02Z",
734
- "customer_id": "cust_84LPwcHJ1jVEpxV1uF9nLLBB",
735
- "tracking_id": "alice.morgan",
736
- "redemption": "r_irOQWUTAjthQwnkn5JQM1V6N"
737
- }
738
- ]
739
- },
740
- "active": true,
741
- "additional_info": ""
742
- }
743
- }
744
- ```
745
-
746
- #### Create customer
747
-
194
+ #### [Update Customer]
748
195
  ```ruby
749
- customer = {
750
- name: "John Doe",
751
- email: "john@email.com",
752
- description: "Sample description about customer",
753
- metadata: {
754
- lang: "en"
755
- }
756
- }
757
-
758
- voucherify.create_customer(customer)
196
+ voucherify.customers.update(customer)
759
197
  ```
760
-
761
- Result:
762
-
763
- ```json
764
- {
765
- "id": "cust_WGG615E92dhOHz7PV9Vo9gk9",
766
- "created_at": "2016-06-12T15:52:49Z",
767
- "description": "Sample description about customer",
768
- "email": "john@email.com",
769
- "metadata": {
770
- "lang": "en"
771
- },
772
- "name": "John Doe",
773
- "object": "customer"
774
- }
775
- ```
776
-
777
- #### Get customer
778
-
198
+ #### [Delete Customer]
779
199
  ```ruby
780
- voucherify.get_customer("cust_WGG615E92dhOHz7PV9Vo9gk9")
781
- ```
200
+ voucherify.customers.delete(customer_id)
201
+ ```
202
+
203
+ ---
204
+
205
+ ### Migration from 0.x
206
+
207
+ Version 1.x of the SDK is not backwards compatible with versions 0.x.
208
+ Changes made in version 1.x mostly relate to grouping methods within namespaces.
209
+ So all you need to do is to follow the list bellow and just replace methods
210
+ with their namespaced equivalent.
211
+
212
+ - `Voucherify.new(params)` - `Voucherify::Client.new(params)`
213
+ - `voucherify.create(voucher)` - [voucherify.vouchers.create](#create-voucher)
214
+ - `voucherify.get(voucher_code)` - [voucherify.vouchers.get](#get-voucher)
215
+ - `voucherify.update(voucher)` - [voucherify.vouchers.update](#update-voucher)
216
+ - `voucherify.list(params)` - [voucherify.vouchers.list](#list-vouchers)
217
+ - `voucherify.enable(voucher_code)` - [voucherify.vouchers.enable](#enable-voucher)
218
+ - `voucherify.disable(voucher_code)` - [voucherify.vouchers.disable](#disable-voucher)
219
+ - `voucherify.publish(campaign_name)` - [voucherify.distributions.publish](#publish-vouchers)
220
+ - `voucherify.validate(voucher_code, params)` - [voucherify.validations.validate](#validate-voucher)
221
+ - `voucherify.redeem(voucher_code, tracking_id)` - [voucherify.redemptions.redeem](#redeem-voucher)
222
+ - `voucherify.redemption(voucher_code)` - [voucherify.redemptions.get_for_voucher](#get-vouchers-redemptions)
223
+ - `voucherify.redemptions(params)` - [voucherify.redemptions.list](#list-redemptions)
224
+ - `voucherify.rollback(redemption_id, tracking_id, reason)` - [voucherify.redemptions.rollback](#rollback-redemptions)
225
+ - `voucherify.create_customer(customer)` - [voucherify.customers.create](#create-customer)
226
+ - `voucherify.get_customer(customer_id)` - [voucherify.customers.get](#get-customer)
227
+ - `voucherify.update_customer(customer)` - [voucherify.customers.update](#update-customer)
228
+ - `voucherify.delete_customer(customer_id)` - [voucherify.customers.delete](#delete-customer)
229
+ - `Utils.round_money(value)` - `Voucherify::Utils.round_money(value)`
230
+ - `Utils.validate_percent_discount(discount)` - `Voucherify::Utils.validate_percent_discount(discount)`
231
+ - `Utils.validate_amount_discount(discount)` - `Voucherify::Utils.validate_amount_discount(discount)`
232
+ - `Utils.validate_unit_discount(discount)` - `Voucherify::Utils.validate_unit_discount(discount)`
233
+ - `Utils.calculate_price(base_price, voucher, [unit_price])` - `Voucherify::Utils.calculate_price(base_price, voucher, [unit_price])`
234
+ - `Utils.calculate_discount(base_price, voucher, [unit_price])` - `Voucherify::Utils.calculate_discount(base_price, voucher, [unit_price])`
235
+
236
+ ---
237
+
238
+ ### Utils
239
+
240
+ #### Available methods
241
+
242
+ - `Voucherify::Utils.round_money(value)`
243
+ - `Voucherify::Utils.validate_percent_discount(discount)`
244
+ - `Voucherify::Utils.validate_amount_discount(discount)`
245
+ - `Voucherify::Utils.validate_unit_discount(discount)`
246
+ - `Voucherify::Utils.calculate_price(base_price, voucher, [unit_price])`
247
+ - `Voucherify::Utils.calculate_discount(base_price, voucher, [unit_price])`
248
+
249
+ ---
250
+
251
+ ## Error handling
782
252
 
783
- Result:
784
-
785
- ```json
786
- {
787
- "id": "cust_WGG615E92dhOHz7PV9Vo9gk9",
788
- "created_at": "2016-06-12T15:52:49Z",
789
- "description": "Sample description about customer",
790
- "email": "john@email.com",
791
- "metadata": {
792
- "lang": "en"
793
- },
794
- "name": "John Doe",
795
- "object": "customer"
796
- }
797
- ```
798
-
799
- #### Update customer
253
+ This voucherify gem uses [rest-client](https://github.com/rest-client/rest-client) under the hood for handling HTTP calls. In case of an HTTP 4xx or 5xx error, a RestClient exception is thrown. The server's specific response is available in `.response` of the exception object.
800
254
 
801
255
  ```ruby
802
- customer = {
803
- id: "cust_WGG615E92dhOHz7PV9Vo9gk9",
804
- description: "Sample description about customer with changes"
805
- }
806
- voucherify.update_customer(customer)
256
+ begin
257
+ voucherify.distributions.publish('test')
258
+ rescue => e
259
+ JSON.parse(e.response)
260
+ end
807
261
  ```
808
262
 
809
- Result:
810
-
811
263
  ```json
812
264
  {
813
- "id": "cust_WGG615E92dhOHz7PV9Vo9gk9",
814
- "created_at": "2016-06-12T15:52:49Z",
815
- "description": "Sample description about customer with changes",
816
- "email": "john@email.com",
817
- "metadata": {
818
- "lang": "en"
819
- },
820
- "name": "John Doe",
821
- "object": "customer"
822
- }
823
- ```
824
-
825
- #### Delete customer
826
-
827
- ```ruby
828
- voucherify.delete_customer("cust_WGG615E92dhOHz7PV9Vo9gk9")
829
- ```
830
-
831
- The response has empty body.
832
-
833
- #### Utilities
834
-
835
- These methods are used to help calculate prices and discounts.
836
-
837
- ```ruby
838
- Utils.calculate_price(base_price, voucher, unit_price)
839
- Utils.calculate_discount(base_price, voucher, unit_price)
840
- ```
841
-
842
- Example:
843
-
844
- ```ruby
845
- voucher = {
846
- category: "New Customers",
847
- type: "DISCOUNT_VOUCHER",
848
- discount: {
849
- percent_off: 10.0,
850
- type: "PERCENT"
851
- },
852
- start_date: "2016-01-01T00:00:00Z",
853
- expiration_date: "2016-12-31T23:59:59Z",
854
- redemption: {
855
- quantity: 1
856
- }
857
- }
858
- ```
859
- ```ruby
860
- Utils.calculate_price(20.0, voucher, 0);
861
- ```
862
-
863
- Result:
864
- ```ruby
865
- 18
866
- ```
867
-
868
- Example:
869
-
870
- ```ruby
871
- voucher = {
872
- category: "New Customers",
873
- type: "DISCOUNT_VOUCHER",
874
- discount: {
875
- amount_off: 7.0,
876
- type: "AMOUNT"
877
- },
878
- start_date: "2016-01-01T00:00:00Z",
879
- expiration_date: "2016-12-31T23:59:59Z",
880
- redemption: {
881
- quantity: 1
882
- }
265
+ "code": 400,
266
+ "message": "Couldn't find any voucher suitable for publication."
883
267
  }
884
268
  ```
885
- ```ruby
886
- Utils.calculate_discount(20.0, voucher, 0);
887
- ```
888
269
 
889
- Result:
890
- ```ruby
891
- 7
892
- ```
270
+ Please refer to [rest-client documentation](https://github.com/rest-client/rest-client#exceptions-see-httpwwww3orgprotocolsrfc2616rfc2616-sec10html) for more detailed information.
893
271
 
894
272
  ## Development
895
273
 
@@ -902,6 +280,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
902
280
  Bug reports and pull requests are welcome on GitHub at https://github.com/rspective/voucherify-ruby-sdk.
903
281
 
904
282
  ## Changelog
283
+ - **2016-12-15** - `1.0.0` - introduced namespaces, unified method names, updated README. Migration from versions 0.x required [migration from version 0.x](#migration-from-0x)
905
284
  - **2016-12-02** - `0.8.2` - support gift vouchers in utils, fix price and discount calculations for amount discounts
906
285
  - **2016-10-03** - `0.8.1` - publish update
907
286
  - **2016-08-02** - `0.8.0` - validate voucher
@@ -923,3 +302,22 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/rspect
923
302
  ## License
924
303
 
925
304
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
305
+
306
+ [Create Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#create-voucher
307
+ [Get Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#vouchers-get
308
+ [Update Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#update-voucher
309
+ [Delete Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#delete-voucher
310
+ [List Vouchers]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#list-vouchers
311
+ [Enable Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#enable-voucher
312
+ [Disable Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#disable-voucher
313
+ [Publish Vouchers]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#publish-voucher
314
+ [Validate Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#validate-voucher
315
+ [Redeem Voucher]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#redeem-voucher
316
+ [List Redemptions]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#list-redemptions
317
+ [Get Voucher's Redemptions]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#vouchers-redemptions
318
+ [Rollback Redemption]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#rollback-redemption
319
+
320
+ [Create Customer]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#create-customer
321
+ [Get Customer]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#read-customer
322
+ [Update Customer]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#update-customer
323
+ [Delete Customer]: https://docs.voucherify.io/reference?utm_source=github&utm_medium=sdk&utm_campaign=acq#delete-customer