ccbill_ruby 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39968023a09afce1fef462927e886edee7bc51e9
4
- data.tar.gz: 4e67d3bf54326c605939a446be2edbbb2477187f
3
+ metadata.gz: 9bcda695920d9205dfd4510acd087a4c01ba5b2f
4
+ data.tar.gz: cac9da0badec1558966a66f3a04721d415e450c3
5
5
  SHA512:
6
- metadata.gz: 3c4c8c0de66eaed747eb7a44c982dc9f1f7f7a119fc73b40439631b6b0661d4627fc9503d672dd9e7ce33ded621c6466d18724f78b59122fb86d11e31dccc52c
7
- data.tar.gz: f46011f2a0a7eb268224cd66aa25bc6c5670a35a1f26d04f54edaf5c1971abe3afc7fc1d691a06080f682c045ae68fe7bd235ef0e930ea1324d5e9e703f17439
6
+ metadata.gz: 7ac9da183ee526c314a571bd7b9a6a1a9f45564c9393239ae3b0ab3cd391d0dfb1cc9ebc674a3dbd88bd6faaa787d45f969d07623adfd55e64c3976cbdf0d196
7
+ data.tar.gz: 34e8110012e4c1d0ab5a24d1bb1695efb227e5f3f8b3dc6be7131535b808bfb76218c5c15b82a4f79ef0dd5d327b06a8921e9df7a4d7dfe46ca8be43944dcf72
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ working_directory: ~/circleci-ccbill-ruby
5
+ docker:
6
+ - image: circleci/ruby:2.4.1-node-browsers
7
+ steps:
8
+ - checkout
9
+ - run: bundle install
10
+ - run: bundle exec rspec spec
data/README.md CHANGED
@@ -1,19 +1,27 @@
1
1
  **Please mail me if any: dmytro.vasin@gmail.com**
2
2
 
3
+ ---
4
+
3
5
  # CCBill SDK for Ruby
4
6
 
7
+ [![Circle CI](https://circleci.com/gh/DmytroVasin/ccbill_ruby.svg?style=shield)](https://circleci.com/gh/DmytroVasin/ccbill_ruby)
8
+
5
9
  Unofficial CCBill SDK for Ruby.
6
10
 
7
11
  This gem provides:
12
+ - Interface for URL generation with simple validation
13
+ - Postback verification (WebHooks)
8
14
  - Easy Install
9
15
  - Getting started guide
10
16
  - Generator that creates
11
- - Approve/Deny callback paths
12
- - Background Post path
17
+ - Approve/Deny callback path
18
+ - Webhook callback path
13
19
  - Url/Form Generator for test and live mode
14
20
 
15
21
 
16
- > Important! CCBill provides two types of payment forms. FlexForms is our newest (and recommended) system. In this gem we use ONLY FlexForms.
22
+ > Important! CCBill provides two types of payment forms.<br/>
23
+ > FlexForms is our newest (and recommended) system.
24
+ > In this gem we use ONLY FlexForms with DynamiPricing.
17
25
 
18
26
 
19
27
  # Getting started
@@ -30,12 +38,12 @@ Next, you need to run the generator:
30
38
  $ rails generate ccbill:install
31
39
  ```
32
40
 
33
- This will create a controller (if one does not exist) and configure it with the default actions. The generator also configures your config/routes.rb file to point to the CCBill controller.
41
+ This will create a controller (if one does not exist) and configure it with the default actions. The generator also configures your `config/routes.rb` file to point to the CCBill controller.
34
42
 
35
43
 
36
44
  ## Example of usage:
37
45
 
38
- Simple version:
46
+ Single billing transaction:
39
47
  ```ruby
40
48
  form = Ccbill::DynamicPricing.new({
41
49
  initial_price_in_cents: 355
@@ -47,15 +55,31 @@ form.valid? #=> True/False
47
55
  form.url #=> URL
48
56
  ```
49
57
 
50
- To prefill the form you can pass additional variables like: `customer_fname`, `customer_lname`, 'address1', etc. [Full list of variables](https://kb.ccbill.com/Webhooks+User+Guide#Payment_Form)
51
-
58
+ Recurring transactions:
52
59
  ```ruby
53
60
  form = Ccbill::DynamicPricing.new({
54
- initial_price_in_cents: 355
61
+ initial_price_in_cents: 3000,
55
62
  initial_period: 30,
56
- order_id: 'Any configuration information',
63
+ recurring_price_in_cents: 100,
64
+ recurring_period: 30,
65
+ num_rebills: 99
66
+ order_id: 'Any configuration information'
67
+ })
68
+
69
+ form.valid? #=> True/False
70
+ form.url #=> URL
71
+ ```
72
+
73
+ To prefill the form you can pass additional variables like: `customer_fname`, `customer_lname`, `address1`, etc.<br/>
74
+ [Full list of variables](https://kb.ccbill.com/Webhooks+User+Guide#Payment_Form)
75
+
76
+ ```ruby
77
+ Ccbill::DynamicPricing.new({
78
+ ...
57
79
  customer_fname: 'Dmytro',
58
- customer_lname: 'Vasin'
80
+ customer_lname: 'Vasin',
81
+ email: 'dmytro.vasin@gmail.com',
82
+ city: 'Dnepr'
59
83
  })
60
84
  ```
61
85
 
@@ -81,6 +105,8 @@ Before reading this part - please read [Setup guide](#setup-guide)
81
105
  config.account = 'account_id'
82
106
  config.sub_account = '0000'
83
107
  config.flexform_id = 'flexform_id'
108
+ config.min_price = '2.95'
109
+ config.max_price = '100'
84
110
  end
85
111
  ```
86
112
 
@@ -88,11 +114,10 @@ Before reading this part - please read [Setup guide](#setup-guide)
88
114
  # app/controllers/callbacks/ccbills_controller.rb
89
115
  module Callbacks
90
116
  class CcbillsController < ApplicationController
91
- # before_action :check_ccbill_callback, only: :create
92
117
 
93
118
  # GET: Redirect from payment system after approval/deny.
94
119
  def show
95
- case response_params[:mppResponse]
120
+ case params[:mppResponse]
96
121
  when 'CheckoutSuccess'
97
122
  flash[:notice] = "Payment was successfully paid"
98
123
  when 'CheckoutFail'
@@ -104,107 +129,100 @@ Before reading this part - please read [Setup guide](#setup-guide)
104
129
  redirect_to root_url
105
130
  end
106
131
 
107
- # POST: Post Back
132
+ # POST: Webhooks
108
133
  def create
109
- postback = CCBill::Postback.new(response_params)
110
-
111
- if postback.approval?
112
- # Do something "Approval" postback.
113
- else
114
- # Do something "Deny" postback.
134
+ begin
135
+ # Your code goes here.
136
+ rescue StandardError => error
137
+ # I assume we should put `rescue` statement because CCBill will call our server again and again untill he will receive 200
138
+ # When there was failure of sending webhooks or the system was under maintenance at the moment.
115
139
  end
116
140
 
117
- head :no_content
141
+ head :ok
118
142
  end
119
143
 
120
- private
121
-
122
- def response_params
123
- @response_params ||= params.except(:controller, :action).to_unsafe_h
124
- end
125
144
  end
126
145
  end
127
146
  ```
128
147
 
129
- # Payment Flow
148
+ # Payment Flow ( via DynamiPricing )
130
149
 
131
- To make some payment through CCBill via DynamiPricing:
132
-
133
- The payment form is the CCBill form that will be displayed to customers after they choose to check out using CCBill. The payment form accepts customer payment information, processes the payment, and returns the customer to your Site through callbacks ( GET ) where you can catche the response and do proper redirect:
150
+ ### TL; DR;
151
+ - On the Site User clicks by generated link. After that user will be redirect to the `payment form`
152
+ - The `payment form` is the CCBill form that will be displayed to customers after they choose to check out using CCBill. The `payment form` accepts customer payment information
153
+ - After processes the payment CCBill returns the customer to the Site through specified callbacks ( GET: `callbacks/ccbills#show` )
154
+ - Besides CCBill will produce another request ( Webhook request ) with status of the payment attempt. ( POST: `callbacks/ccbills#create` )
134
155
 
135
156
  ### Step 1:
136
157
 
137
- 1. You should generate LINK that contains information about order/subscription
158
+ 1. You should generate link.<br/>
159
+ That link should contains information about order/subscription or etc. ( What order exactly was paid )
138
160
 
139
- This gem will help you in this, next script will generate link:
161
+ This gem will help you in this case. Next script will generate link:
140
162
  ```ruby
141
163
  Ccbill::DynamicPricing.new({
142
164
  initial_price_in_cents: 355
143
165
  initial_period: 30,
144
- order_id: 'Any configuration information'
166
+ order_id: 'Any additional information'
145
167
  }).url
146
168
  ```
147
169
 
148
- This link contains variables: `initial_price`, `initial_period` and additional variable `order_id`. To enhance security, that url contains `FormDigest` value. The formDigest value is a hex-encoded MD5 hash, calculated using a combination of the fields and a salt value. [More information](https://kb.ccbill.com/Dynamic+Pricing+User+Guide#Generating_the_MD5_Hash)
170
+ This link contains variables: `initial_price`, `initial_period` and additional variable `order_id`.<br/>
171
+ To enhance security, generated url will contains `formDigest` value. The `formDigest` value is a hex-encoded MD5 hash, calculated using a combination of the fields and a salt value. [Read More](https://kb.ccbill.com/Dynamic+Pricing+User+Guide#Generating_the_MD5_Hash)
149
172
 
150
173
 
151
174
  ### Step 2:
152
175
 
153
- 2. By clicking on this link user will be redirected to the CCBill payment form.
154
- This form is generated by admin. Find out more at [Configure your CCBill Account:](#configure-your-ccbill-account) section.
176
+ 2. By clicking on this link user will be redirected to the CCBill `payment form`.<br/>
177
+ This form was generated by the admin inside CCBill admin panel.<br/>
178
+ Find out more at [Configure your CCBill Account](#configure-your-ccbill-account) section.
155
179
 
156
180
  When user fill-in all fields. He can follow 2 way: `Approve` and `Deny`
157
181
 
158
182
  But here is two thing:
159
- 1 On `Deny` response: App will propose to Try Again (User will stay at the payment system)
160
- 2 On `Deny` response: App will receive `Deny` postback. ( `callbacks/ccbills#create` ). With Deny attributes.
161
- 3 To Receive `Deny` redirect:
162
- > The reason you aren’t redirected to denial URL is because our system sees these declines as ‘soft’ declines, and by default, you need to have at least 3 soft declines in a row until you are redirected to denial url. So if you want to test denial redirection, you will need to click ‘Try again’ and fill out the credit card number for three consecutive times and you will be redirected. If the consumer is ‘hard’ declined(for example transaction is denied by consumer’s bank), he would be redirected after first form submission. Additionally, we can turn off this rule to have soft denial three times before redirection and if you would like us to do so, please confirm.
163
- 4. Test Cards
164
- [Test cards](https://kb.ccbill.com/How+do+I+set+up+a+user+to+process+test+transactions) you can find here. But one thing you should remember: Only `CVV` metters:
165
- > When performing test transactions in Sandbox mode, cvv2 higher then 300 will result in approval even though you used denial credit card. If you try to test it in live mode, you would receive denial no matter what cvv2 you are using.
183
+ 1. On `Deny` response: App will propose to Try Again (User will stay at the payment system)
184
+ 2. On `Deny` response: App will receive `Deny` webhook callback (`callbacks/ccbills#create`) that will contain `Deny` attributes.
185
+ 3. To Receive `Deny` redirect user must do 3 `Deny` attempt.
166
186
 
167
- ### Step 2:
187
+ > Explanation: The reason you aren’t redirected to denial URL is because our system sees these declines as ‘soft’ declines, and by default, you need to have at least 3 soft declines in a row until you are redirected to denial url. So if you want to test denial redirection, you will need to click ‘Try again’ and fill out the credit card number for three consecutive times and you will be redirected. If the consumer is ‘hard’ declined(for example transaction is denied by consumer’s bank), he would be redirected after first form submission. Additionally, we can turn off this rule to have soft denial three times before redirection and if you would like us to do so, please confirm.
168
188
 
169
- `Approval Path` and `Deny Path` we set up [here](#create-an-approval-url)
189
+ 4. Test Cards<br/>
190
+ Test cards you can [find here](https://kb.ccbill.com/How+do+I+set+up+a+user+to+process+test+transactions).<br/>
191
+ But one thing you should remember: Only `CVV` metters:<br/>
170
192
 
171
- **Approval Path**
193
+ > Explanation: When performing test transactions in Sandbox mode, cvv2 higher then 300 will result in approval even though you used denial credit card. If you try to test it in live mode, you would receive denial no matter what cvv2 you are using.
172
194
 
173
- This is the path customers take when their transaction is approved. The Approval Tile is always below the Primary and Deny Tile. When editing the Approval Path, your options are limited.
195
+ `Approval Path` and `Deny Path` was specified when we create FlexForm [here](#create-a-new-flexform)
174
196
 
175
- **Deny Path**
197
+ **Approval Path**<br/>
198
+ Customer will follow by this path if his transaction will be approved. You can find `Approval Tile` below the `Primary` and `Deny Tile`.
176
199
 
200
+ **Deny Path**<br/>
177
201
  This is the path consumers take when they are declined on a transaction. They will be redirected to the deny path to try again. The Deny Tile is always to the right of the Primary Tile.
178
202
 
179
- To set up a Deny Path:
180
-
181
- - Click the Deny Tile. A new window has opened. It will be very similar to the one you saw when you created the Primary Tile.
182
- - Select one of several redirect options along the left side of the screen.
183
- - New Form. Create a new FlexForm as you did for the Primary Tile.
184
- - Existing Form. Use a previously made Form.
185
- - URL. Add an external or internal link. Send customers back to your website or to a third party payment form.
186
-
187
- ![Deny Path](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/redirect_path.png)
203
+ ![Approval and Deny paths](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/approval-and-deny.png)
188
204
 
189
205
 
190
206
  ### Step 3:
191
- After previouse steps, ccbill returns the customer to your Site through callbacks ( GET ) where you can catche the response and do proper redirect:
207
+ After previouse steps, ccbill redirects the customer to the Site through callbacks ( GET ) where you can catche the response and do proper redirect:
192
208
 
193
209
  ```ruby
194
210
  callbacks_ccbill GET /callbacks/ccbill(.:format) callbacks/ccbills#show
195
- POST /callbacks/ccbill(.:format) callbacks/ccbills#create
196
211
  ```
197
212
 
198
213
  ### Step 4:
214
+ When a transaction is approved or denied, data will be sent to the Webhooks URL, if that event has been selected within the configuration. The data sent will include everything passed into the payment form along with the data entered into the payment form by the consumer, excluding payment information. This data can be parsed and handled
199
215
 
200
- Postback: According to `POST` action in your controller.
201
-
202
- Background Post allows Merchants to receive data posts from our system to a script that the Merchant creates. Merchants can parse that data from the script into their databases/tables for member tracking. Background Post only works for NEW transactions.
203
-
204
- Some kind of background callback to the app that happens on each attempt to Pay
216
+ Webhook: According to `POST` action in your controller:<br/>
217
+ ```ruby
218
+ POST /callbacks/ccbill(.:format) callbacks/ccbills#create
219
+ ```
205
220
 
206
- This callback contains a lot of information of the attempt: [Background Post](https://kb.ccbill.com/Background+Post)
221
+ Webhooks is some kind of background callback to the app that happens on each attempt to Pay.<br>
222
+ This callback contains a lot of information of the attempt. For example: [NewSaleSuccess](https://kb.ccbill.com/Webhooks+User+Guide#NewSaleSuccess)
207
223
 
224
+ > WebHooks vs Background Post
225
+ > When you use webhooks, there is no need to use Postback also. The main difference is that Postback only sends notifications for approved and denied transactions, and webhooks sends posts for all existing events, for example, renewal, cancellation, failed rebill, refund, chargeback, void, etc. The complete list of events can be found [here](https://kb.ccbill.com/Webhooks+User+Guide#Webhooks_Notifications)
208
226
 
209
227
 
210
228
  # Setup guide
@@ -272,7 +290,7 @@ Please work with your CCBill support representative to activate Dynamic Pricing
272
290
 
273
291
  Please note that if Dynamic Pricing is enabled on the subaccount level, ALL signup forms on that subaccount must use Dynamic Pricing in order to function correctly. This includes forms created on the subaccount prior to Dynamic Pricing being enabled. If Dynamic Pricing is enabled only on a particular form and not the entire subaccount, other forms on that subaccount will not be required to use Dynamic Pricing.
274
292
 
275
- ![URL Library](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/url_library.png)
293
+ ![Dynamic Pricing](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/dynamic-price.png)
276
294
 
277
295
  ### Creating a Salt / Encryption Key
278
296
 
@@ -298,10 +316,10 @@ Here is standart [Getting Started with Flex Froms](https://kb.ccbill.com/FlexFor
298
316
 
299
317
  #### Visit FlexForms:
300
318
  - Ensure All is selected in the top Client Account drop-down menu. FlexForms are not specific to sub accounts, and cannot be managed when a sub account is selected.
301
- - Navigate to the FlexForms Systems tab in the top menu bar and select FlexForms Payment Links. All existing forms will be displayed in a table.
319
+ - Navigate to the `FlexForms Systems` tab in the top menu bar and select `FlexForms Payment Links`. All existing forms will be displayed in a table.
302
320
  - Make sure that you in sendbox ( Top left corner )
303
321
 
304
- #### Create an Approval URL
322
+ #### Create Library of URLs (Approval and Deny)
305
323
 
306
324
  - Click the **URLs Library** button in the upper-right to create a new URL. The Saved URLs Editor dialog displays.
307
325
  - Create Payment Success URL
@@ -312,15 +330,14 @@ Here is standart [Getting Started with Flex Froms](https://kb.ccbill.com/FlexFor
312
330
  - Click Save to commit your changes.
313
331
 
314
332
  > Important:
315
- > 1. Do not create alot of flex-form. You can't delete them!
316
- > 2. This is URLS ( GET ) where user will be redirected after success/deny payment.
317
- > 3. We set `mppResponse=CheckoutSuccess` and `mppResponse=CheckoutFail` because we use this attribute at `callbacks/ccbills#show` action.
333
+ > 2. This is URLS ( GET ) will be used to specify where CCBill should redirect User after success/deny payment.
334
+ > 3. We set `mppResponse=CheckoutSuccess` and `mppResponse=CheckoutFail` because we use this attribute at `callbacks/ccbills#show` action to determine kind of response (success/fail).
318
335
 
319
336
  ![URLs Editor](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/url_editor.png)
320
337
 
321
338
  #### Create a New FlexForm
322
339
 
323
- - Click the `Add New** button in the upper-left to create a new form.
340
+ - Click the **Add New** button in the upper-left to create a new form.
324
341
  - The **A New Form** dialog is displayed:
325
342
  - **Payment Flow Name**. At the top, enter a name for the new payment flow (this will be different than the form name, as a single form can be used in multiple flows). Forexample: 'Dev Form'
326
343
  - **Form Name**. Under Form Name, enter a name for the form. Forexample: '001ff'
@@ -329,54 +346,92 @@ Here is standart [Getting Started with Flex Froms](https://kb.ccbill.com/FlexFor
329
346
  - Save the form
330
347
  - Edit the Flow
331
348
  - Approval redirect to the Site
332
- - Click the arrow button to the left of your new flow to view the details. ( Screenshot below )
349
+ - Click the arrow button to the left of your new flow to view the details. Approval Tile.
333
350
  - Under the green Approve arrow, click the square to modify the action.
334
351
  - **Approval URL**. In the left menu, select A URL. Select **Select a Saved URL** and select the URL your created earlier (e.g. Payment Success).
335
352
  - **Redirect Time**. Select a redirect time of 1 second using the slider at the bottom and save the form. ( e.g. 4 seconds )
336
353
  - Deny redirect to the Site
337
- - Under the red Deny arrow, click the square to modify the action.
338
- - **Approval URL. In the left menu, select A URL. Select **Select a Saved URL** and select the URL your created earlier (e.g. Payment Decline`).
354
+ - Under the red Deny arrow, click the square to modify the action. Deny Tile.
355
+ - **Approval URL**. In the left menu, select A URL. Select **Select a Saved URL** and select the URL your created earlier (e.g. `Payment Decline`).
339
356
  - **Redirect Time**. Select a redirect time of 1 second using the slider at the bottom and save the form. ( e.g. 7 seconds )
340
357
  - Flex ID. Make note of the Flex ID: this value will be entered into the your configuration file. ( `config/initializers/ccbill.rb` )
341
358
 
359
+ > You may read how to setup instant redirect [here](#dev-expirience)
342
360
 
343
- #### Background Post
361
+ > Important:
362
+ > Do not create alot of FlexForm's. You can't delete them!
344
363
 
345
- While still in the **Sub Account Admin** section, select **Advanced** from the left menu. Notice the top section titled **Background Post Information**. We will be modifying the **Approval Post URL** and **Denial Post URL** fields.
364
+ ![Deny Path](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/redirect_path.png)
346
365
 
347
- Path | URL
348
- --- | ---
349
- **Approval Post URL** | `http://[SiteHost or Ngrok]/callbacks/ccbill`
350
- **Denial Post URL** | `http://[SiteHost or Ngrok]/callbacks/ccbill`
351
366
 
352
- CCBill calls this URL in background.
367
+ #### Webhooks
353
368
 
354
- Note: That will be `POST` request. In our case It will call `callbacks/ccbills#create` action. In this action based on patams we will find-out what request was called.
369
+ In your CCBill admin interface, navigate to **Sub Account Admin** section, select **Webhooks** from the left menu.<br>
370
+ Fill in `Webhook URL` text box with the `http://[SiteHost or Ngrok]/callbacks/ccbill` url. CCBill will call specified URL in background.<br>
371
+ Make sure to check 'all' check boxes on this page and pick JSON Webhook Format<br>
355
372
 
356
- ![Background Post Information](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/background_post_information.png)
373
+ Note: That will be `POST` request.<br>
374
+ In our case It will call `callbacks/ccbills#create` action.<br>
375
+ In this action based on params we will find-out what request was called.
357
376
 
358
- **Your CCBill account is now configured**
377
+ ![Webhook information](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/webhooks.png)
359
378
 
379
+ **:sparkles: Your CCBill account is now configured :sparkles:**
360
380
 
361
- # Go To LIVE:
362
381
 
363
- TODO:
382
+ # Price Restrictions
383
+
384
+ Price Minimums and Maximums<br/>
385
+ All Merchants are assigned a default structure in line with the following:
386
+
387
+ Pricing<br/>
388
+ Minimum: $2.95 USD<br/>
389
+ Maximum: $100.00 USD<br/>
390
+
391
+ Time Periods<br/>
392
+ Initial Period: 2-365 Days<br/>
393
+ Rebill Period: 30, 60, or 90 Days<br/>
394
+
395
+ > Changes to your available price ranges require upper management approval. If you would like to make changes, please contact CCBill Merchant Support. We'll talk to you about the changes you want and submit your request to the right people. This process can take one or two business days to complete.
396
+
397
+
398
+ # Response Digest Value:
399
+
400
+ In [Dynamic Pricing article](https://kb.ccbill.com/Dynamic+Pricing#Response_Digest_Value) was described that you can test digest value from response. That is true ONLY for `production` mode. In test mode digets value is not match.
401
+
402
+ Gem allows you to test that via:
403
+
404
+ ```ruby
405
+ postback = CCBill::Postback.new(params)
406
+ postback.verified? #=> True/False
407
+ ```
408
+
409
+ > Important! This method work only in 'non-test' mode.
410
+ > Important! This method work only for `NewSaleSuccess` and `NewSaleFailure`
411
+
412
+
413
+ # Go To LIVE:
364
414
 
365
415
  The LINKS that you get from the Sandbox Mode page are different from the links that you get from the Live Mode page
366
416
 
417
+ Do not forget to create another FlexForm for the production env.
418
+
367
419
  Please read next:
368
420
  - [FlexForms Sandbox](https://kb.ccbill.com/FlexForms+Sandbox?page_ref_id=452)
369
421
  - [FlexForms Form Status and Live Mode](https://kb.ccbill.com/FlexForms+Form+Status+and+Live+Mode?page_ref_id=453)
370
422
 
371
423
  # Dev Expirience:
372
424
 
373
- TODO:
374
-
375
- TODO: NGrok.
376
-
377
- TODO: 3) You are able to check the number and amount of test transactions you had in selected timeframe. In order to do so, please navigate to Reports >> Alphabetical list >> C >> Credit/check transactions >> select date range and select Test transactions from Options dropdown menu.
378
-
379
- TODO: !!! All prices must be between $2.95 and $100.
425
+ 1. Ngrok. For the local machine use `ngrok` to set real links from the Ccbill.
426
+ 2. Deny/Approval paths - Write to support to set "Redirect time in seconds:" to "Immediately". Without this option after approve/deny user will be redirected to the blank page with the URL of redirect ( image below ) and that page can't be customized, with this option user will instantly be redirected.
427
+ ![Redirect After Aprove](https://raw.githubusercontent.com/DmytroVasin/ccbill_ruby/master/images/redirect_after_approval.png)
428
+ 3. Check transactions: Admin are able to check the number and amount of test transactions you had in selected timeframe. In order to do so, please navigate to Reports >> Alphabetical list >> C >> Credit/check transactions >> select date range and select Test transactions from Options dropdown menu.
429
+ 4. All prices must be between [$2.95 and $100](https://kb.ccbill.com/Price+Minimums+and+Maximums)
430
+ 5. In development mode you can't check transaction from the point 3.
431
+ 6. Test transaction can't be "cancelled, void, etc". The only way you could test is to use real credit card and then refund the subscription after it rebills. Personnaly I tested only NewSaleSuccess, NewSaleFailure responses.
432
+ 7. All received responses I attached to the [Responses](https://github.com/DmytroVasin/ccbill_ruby/tree/master/responses). ( I little bit changed own info )
433
+ 8. Response Digest Value. In [Dynamic Pricing article](https://kb.ccbill.com/Dynamic+Pricing#Response_Digest_Value) was described that you can test digest value from response. That is true ONLY for `production` mode. In test mode digets value is not match.
434
+ 9. Do not create alot of FlexForm's. You can't delete them
380
435
 
381
436
 
382
437
  # Useful Links:
@@ -386,8 +441,11 @@ TODO: !!! All prices must be between $2.95 and $100.
386
441
  * [FlexForms Sandbox](https://kb.ccbill.com/FlexForms+Sandbox?page_ref_id=452)
387
442
  * [FlexForms Form Status and Live Mode](https://kb.ccbill.com/FlexForms+Form+Status+and+Live+Mode?page_ref_id=453)
388
443
  * [Test Transactions and Credit Cards](https://kb.ccbill.com/How+do+I+set+up+a+user+to+process+test+transactions)
389
- * [Background Post](https://kb.ccbill.com/Background+Post)
390
444
  * [Webhooks - prefil variables](https://kb.ccbill.com/Webhooks+User+Guide#Payment_Form)
445
+ * [Price Minimums and Maximums](https://kb.ccbill.com/Price+Minimums+and+Maximums)
446
+ * [Responses](https://github.com/DmytroVasin/ccbill_ruby/tree/master/responses)
447
+
448
+ TODO: Datalink.
391
449
 
392
450
  # License
393
451
 
data/ccbill_ruby.gemspec CHANGED
@@ -36,4 +36,5 @@ Gem::Specification.new do |gem|
36
36
  gem.add_development_dependency "rake", "~> 10.0"
37
37
  gem.add_development_dependency "rspec", "~> 3.6.0"
38
38
  gem.add_development_dependency "pry"
39
+ gem.add_development_dependency "json"
39
40
  end
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -5,4 +5,6 @@ CCBill.configure do |config|
5
5
  config.account = 'account_id'
6
6
  config.sub_account = '0000'
7
7
  config.flexform_id = 'flexform_id'
8
+ config.min_price = '2.95'
9
+ config.max_price = '100'
8
10
  end
@@ -1,10 +1,9 @@
1
1
  module Callbacks
2
2
  class CcbillsController < ApplicationController
3
- # before_action :check_ccbill_callback, only: :create
4
3
 
5
4
  # GET: Redirect from payment system after approval/deny.
6
5
  def show
7
- case response_params[:mppResponse]
6
+ case params[:mppResponse]
8
7
  when 'CheckoutSuccess'
9
8
  flash[:notice] = "Payment was successfully paid"
10
9
  when 'CheckoutFail'
@@ -16,23 +15,17 @@ module Callbacks
16
15
  redirect_to root_url
17
16
  end
18
17
 
19
- # POST: Post Back
18
+ # POST: Webhooks
20
19
  def create
21
- postback = CCBill::Postback.new(response_params)
22
-
23
- if postback.approval?
24
- # Do something "Approval" postback.
25
- else
26
- # Do something "Deny" postback.
20
+ begin
21
+ # Your code goes here.
22
+ rescue StandardError => error
23
+ # I assume we should put `rescue` statement because CCBill will call our server again and again untill he will receive 200
24
+ # When there was failure of sending webhooks or the system was under maintenance at the moment.
27
25
  end
28
26
 
29
- head :no_content
27
+ head :ok
30
28
  end
31
29
 
32
- private
33
-
34
- def response_params
35
- @response_params ||= params.except(:controller, :action).to_unsafe_h
36
- end
37
30
  end
38
31
  end
@@ -8,6 +8,9 @@ module CCBill
8
8
  attr_accessor :salt
9
9
  attr_accessor :default_currency
10
10
 
11
+ attr_accessor :min_price
12
+ attr_accessor :max_price
13
+
11
14
  attr_accessor :account
12
15
  attr_accessor :sub_account
13
16
 
@@ -19,6 +22,9 @@ module CCBill
19
22
  @mode = :test
20
23
  @default_currency = '840' # USD
21
24
 
25
+ @min_price = 2.95
26
+ @max_price = 100
27
+
22
28
  @test_endpoint = TEST_ENDPOINT
23
29
  @live_endpoint = LIVE_ENDPOINT
24
30
  end
@@ -5,11 +5,12 @@ module CCBill
5
5
  attr_accessor :variables, :config, :errors
6
6
 
7
7
  def initialize(options = {})
8
+ self.config = CCBill.configuration
9
+
8
10
  fail_on_price_set(options)
9
11
 
10
12
  modified_options = modify_params(options)
11
13
 
12
- self.config = CCBill.configuration
13
14
  self.variables = {
14
15
  account: config.account,
15
16
  sub_account: config.sub_account,
@@ -18,7 +19,7 @@ module CCBill
18
19
  end
19
20
 
20
21
  def url
21
- raise DynamicPricingError.new(errors.join(' ')) if !valid?
22
+ raise DynamicPricingError.new(self.errors.join(' ')) if !valid?
22
23
 
23
24
  variables[:form_digest] = encode_form_digest
24
25
 
@@ -26,23 +27,23 @@ module CCBill
26
27
  end
27
28
 
28
29
  def valid?
29
- @errors = []
30
+ self.errors = []
30
31
 
31
32
  required_fields.each do |field|
32
- @errors << "#{field} is required." if !variables[field]
33
+ self.errors << "#{field} is required." if !variables[field]
33
34
  end
34
35
 
35
- unless (2.96..99.99).include?(variables[:initial_price].to_f)
36
- @errors << 'Initial price must be between $2.95 and $100.'
36
+ unless (config.min_price.to_f..config.max_price.to_f).include?(variables[:initial_price].to_f)
37
+ self.errors << "Initial price must be between $#{config.min_price} and $#{config.max_price}."
37
38
  end
38
39
 
39
40
  if recurring?
40
- unless (2.96..99.99).include?(variables[:recurring_price].to_f)
41
- @errors << 'Recurring price must be between $2.95 and $100.'
41
+ unless (config.min_price.to_f..config.max_price.to_f).include?(variables[:recurring_price].to_f)
42
+ self.errors << "Recurring price must be between $#{config.min_price} and $#{config.max_price}."
42
43
  end
43
44
  end
44
45
 
45
- @errors.empty?
46
+ self.errors.empty?
46
47
  end
47
48
 
48
49
  private
@@ -6,34 +6,32 @@ module CCBill
6
6
  self.response_params = response_params
7
7
  end
8
8
 
9
- def approval?
10
- !denial?
9
+ def verified?
10
+ # NOTE: https://github.com/DmytroVasin/ccbill_ruby#response-digest-value
11
+ return true if CCBill.configuration.test?
12
+
13
+ response_params['dynamicPricingValidationDigest'] == encode_digest_response
11
14
  end
12
15
 
13
- def denial?
14
- [:reasonForDeclineCode, :reasonForDecline, :denialId].any? do |key|
16
+ private
17
+
18
+ def denied?
19
+ ['failureCode', 'failureReason'].any? do |key|
15
20
  !response_params[key].to_s.strip.empty?
16
21
  end
17
22
  end
18
23
 
19
- def verified?
20
- fail 'NOTE: Does not work on test env - Did not check for production.'
21
- response_params[:responseDigest] == encode_digest_response
22
- end
23
-
24
- private
25
-
26
24
  def encode_digest_response
27
- verify_fields = if approval?
25
+ verify_fields = if denied?
28
26
  [
29
- response_params[:subscription_id],
30
- '1',
27
+ response_params['transactionId'],
28
+ '0',
31
29
  CCBill.configuration.salt
32
30
  ]
33
31
  else
34
32
  [
35
- response_params[:denialId],
36
- '0',
33
+ response_params['subscriptionId'],
34
+ '1',
37
35
  CCBill.configuration.salt
38
36
  ]
39
37
  end
@@ -1,3 +1,3 @@
1
1
  module CCBill
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.4'
3
3
  end
@@ -0,0 +1,9 @@
1
+ {
2
+ "eventType": "Cancellation",
3
+ "clientAccnum":"007687",
4
+ "clientSubacc":"0001",
5
+ "reason":"Satisfied Customer",
6
+ "source":"customerSupport",
7
+ "subscriptionId":"0117240102000000048",
8
+ "timestamp":"2017-07-01 05:18:43"
9
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "eventType": "Chargeback",
3
+ "accountingAmount":"19.99",
4
+ "accountingCurrency":"USD",
5
+ "accountingCurrencyCode":"840",
6
+ "amount":"19.99",
7
+ "clientAccnum":"007687",
8
+ "clientSubacc":"0001",
9
+ "currency":"USD",
10
+ "currencyCode":"840",
11
+ "reason":"Charged Back on 05\/05\/2016",
12
+ "subscriptionId":"02161032010000000000",
13
+ "timestamp":"2016-05-05 04:37:59",
14
+ "transactionId":"02161032010000000000"
15
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "accountingCurrency":"USD",
3
+ "accountingCurrencyCode":"840",
4
+ "accountingInitialPrice":"18.0",
5
+ "accountingRecurringPrice":"18.0",
6
+ "address1":"asdasdasd",
7
+ "billedCurrency":"USD",
8
+ "billedCurrencyCode":"840",
9
+ "billedInitialPrice":"18.00",
10
+ "billedRecurringPrice":"18.00",
11
+ "cardType":"VISA",
12
+ "city":"asdasdad",
13
+ "clientAccnum":"007687",
14
+ "clientSubacc":"0001",
15
+ "country":"UA",
16
+ "dynamicPricingValidationDigest":"ed7d71a3a7d34d4be2f1153d5058538c",
17
+ "email":"test@gmail.com",
18
+ "failureCode":"BE-900",
19
+ "failureReason":"transaction declined",
20
+ "firstName":"Mellowcollen",
21
+ "flexId":"08db4ae9-0000-0000-0000-e0275cf91c00",
22
+ "formName":"003ff",
23
+ "ipAddress":"217.20.178.5",
24
+ "initialPeriod":"30",
25
+ "lastName":"asdasdasd",
26
+ "paymentType":"CREDIT",
27
+ "postalCode":"123123",
28
+ "priceDescription":"$18.00(USD) for 30 days then $18.00(USD) recurring every 30 days",
29
+ "rebills":"99",
30
+ "recurringPeriod":"30",
31
+ "recurringPriceDescription":"$18.00(USD) recurring every 30 days",
32
+ "referringUrl":"http://localhost:3000/users/00000",
33
+ "state":"Chernihivs`ka Oblast`",
34
+ "subscriptionCurrency":"USD",
35
+ "subscriptionCurrencyCode":"840",
36
+ "subscriptionInitialPrice":"18.00",
37
+ "subscriptionRecurringPrice":"18.00",
38
+ "timestamp":"2017-08-28 07:08:09",
39
+ "transactionId":"0117240102000000048",
40
+ "X-clientSubacc":"0004",
41
+ "X-clientAccnum":"947687",
42
+ "X-email":"collenmellow@gmail.com",
43
+ "X-customer_fname":"Mellowcollen",
44
+ "X-mpp_model_id":"00000",
45
+ "X-mpp_subscriber_id":"00000",
46
+ "X-numRebills":"99",
47
+ "X-recurringPeriod":"30",
48
+ "X-initialPeriod":"30",
49
+ "X-currencyCode":"840",
50
+ "X-formDigest":"ed7d71a3a7d34d4be2f1153d5058538c",
51
+ "X-recurringPrice":"18.00",
52
+ "X-initialPrice":"18.00",
53
+ "X-city":"",
54
+ "eventType":"NewSaleFailure",
55
+ "eventGroupType":"Subscription",
56
+ "controller":"callbacks/ccbills",
57
+ "action":"create"
58
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "accountingCurrency":"USD",
3
+ "accountingCurrencyCode":"840",
4
+ "accountingInitialPrice":"18.0",
5
+ "accountingRecurringPrice":"18.0",
6
+ "address1":"asdasdasd",
7
+ "billedCurrency":"USD",
8
+ "billedCurrencyCode":"840",
9
+ "billedInitialPrice":"18.00",
10
+ "billedRecurringPrice":"18.00",
11
+ "bin":"444444",
12
+ "cardType":"VISA",
13
+ "city":"asdasdad",
14
+ "clientAccnum":"007687",
15
+ "clientSubacc":"0001",
16
+ "country":"UA",
17
+ "dynamicPricingValidationDigest":"ed7d71a3a7d34d4be2f1153d5058538c",
18
+ "email":"test@gmail.com",
19
+ "expDate":"0322",
20
+ "firstName":"Mellowcollen",
21
+ "flexId":"08db4ae9-0000-0000-0000-e0275cf91c00",
22
+ "formName":"003ff",
23
+ "initialPeriod":"30",
24
+ "ipAddress":"217.20.178.5",
25
+ "last4":"6666",
26
+ "lastName":"asdasdasd",
27
+ "nextRenewalDate":"2017-09-27",
28
+ "paymentAccount":"5bbb1dc47a3595bdfedce0000001cd3",
29
+ "paymentType":"CREDIT",
30
+ "postalCode":"123123",
31
+ "priceDescription":"$18.00(USD) for 30 days then $18.00(USD) recurring every 30 days",
32
+ "rebills":"99",
33
+ "recurringPeriod":"30",
34
+ "recurringPriceDescription":"$18.00(USD) recurring every 30 days",
35
+ "referringUrl":"http://localhost:3000/users/000000",
36
+ "state":"Chernihivs`ka Oblast`",
37
+ "subscriptionCurrency":"USD",
38
+ "subscriptionCurrencyCode":"840",
39
+ "subscriptionId":"0117240102000000049",
40
+ "subscriptionInitialPrice":"18.00",
41
+ "subscriptionRecurringPrice":"18.00",
42
+ "subscriptionTypeId":"0000000464",
43
+ "timestamp":"2017-08-28 07:08:52",
44
+ "transactionId":"0117240102000000049",
45
+ "X-clientSubacc":"007687",
46
+ "X-clientAccnum":"0001",
47
+ "X-email":"collenmellow@gmail.com",
48
+ "X-customer_fname":"Mellowcollen",
49
+ "X-mpp_model_id":"000000",
50
+ "X-mpp_subscriber_id":"00000",
51
+ "X-numRebills":"99",
52
+ "X-recurringPeriod":"30",
53
+ "X-initialPeriod":"30",
54
+ "X-currencyCode":"840",
55
+ "X-formDigest":"ed7d71a3a7d34d4be2f1153d5058538c",
56
+ "X-recurringPrice":"18.00",
57
+ "X-initialPrice":"18.00",
58
+ "X-city":"",
59
+ "eventType":"NewSaleSuccess",
60
+ "eventGroupType":"Subscription",
61
+ "controller":"callbacks/ccbills",
62
+ "action":"create"
63
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "accountingCurrency":"USD",
3
+ "accountingCurrencyCode":"840",
4
+ "accountingInitialPrice":"45.0",
5
+ "address1":"test",
6
+ "billedCurrency":"USD",
7
+ "billedCurrencyCode":"840",
8
+ "billedInitialPrice":"45.00",
9
+ "billedRecurringPrice":"0.00",
10
+ "bin":"444444",
11
+ "cardType":"VISA",
12
+ "city":"test",
13
+ "clientAccnum":"007687",
14
+ "clientSubacc":"0001",
15
+ "country":"UA",
16
+ "dynamicPricingValidationDigest":"8f32cc52c16e9d0117a6a52c3a7325a1",
17
+ "email":"test@gmail.com",
18
+ "expDate":"0219",
19
+ "firstName":"Mellowcollen",
20
+ "flexId":"08db4ae9-0000-0000-0000-e0275cf91c00",
21
+ "formName":"00001",
22
+ "initialPeriod":"90",
23
+ "ipAddress":"000.20.000.5",
24
+ "last4":"6666",
25
+ "lastName":"test",
26
+ "paymentAccount":"00000000003595bdfedce0000000000",
27
+ "paymentType":"CREDIT",
28
+ "postalCode":"123123",
29
+ "priceDescription":"$45.00(USD) for 90 days (non-recurring)",
30
+ "rebills":"0",
31
+ "recurringPeriod":"0",
32
+ "referringUrl":"http://localhost:3000/users/00000",
33
+ "state":"Chernihivs`ka Oblast`",
34
+ "subscriptionCurrency":"USD",
35
+ "subscriptionCurrencyCode":"840",
36
+ "subscriptionId":"0117240102000000041",
37
+ "subscriptionInitialPrice":"45.00",
38
+ "subscriptionRecurringPrice":"0.00",
39
+ "subscriptionTypeId":"0000000891",
40
+ "timestamp":"2017-08-28 06:06:03",
41
+ "transactionId":"0117240102000000041",
42
+ "X-clientSubacc":"007687",
43
+ "X-clientAccnum":"0001",
44
+ "X-initialPrice":"45.00",
45
+ "X-city":"",
46
+ "X-email":"collenmellow@gmail.com",
47
+ "X-customer_fname":"Mellowcollen",
48
+ "X-mpp_model_id":"00000",
49
+ "X-mpp_subscriber_id":"000000",
50
+ "X-initialPeriod":"90",
51
+ "X-formDigest":"8f32cc52c16e9d0117a6a52c3a7325a1",
52
+ "X-currencyCode":"840",
53
+ "eventType":"NewSaleSuccess",
54
+ "eventGroupType":"Subscription"
55
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "eventType": "Void",
3
+ "accountingAmount":"48.99",
4
+ "accountingCurrency":"USD",
5
+ "accountingCurrencyCode":"840",
6
+ "amount":"48.99",
7
+ "clientAccnum":"007687",
8
+ "clientSubacc":"0001",
9
+ "currency":"USD",
10
+ "currencyCode":"840",
11
+ "reason":"Threatened CB",
12
+ "subscriptionId":"0000006401000006464",
13
+ "timestamp":"2017-01-27 13:31:12",
14
+ "transactionId":"0000000001000006464"
15
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ccbill_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmytro Vasin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-28 00:00:00.000000000 Z
11
+ date: 2017-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: Provides interfaces to interact with CCBill services.
84
98
  email:
85
99
  - dmytro.vasin@gmail.com
@@ -87,6 +101,7 @@ executables: []
87
101
  extensions: []
88
102
  extra_rdoc_files: []
89
103
  files:
104
+ - ".circleci/config.yml"
90
105
  - ".gitignore"
91
106
  - ".rspec"
92
107
  - CODE_OF_CONDUCT.md
@@ -98,13 +113,15 @@ files:
98
113
  - bin/console
99
114
  - bin/setup
100
115
  - ccbill_ruby.gemspec
101
- - images/background_post_information.png
116
+ - images/approval-and-deny.png
102
117
  - images/billing_tools.png
103
118
  - images/disabling_user_management.png
119
+ - images/dynamic-price.png
104
120
  - images/encryption_key.png
121
+ - images/redirect_after_approval.png
105
122
  - images/redirect_path.png
106
123
  - images/url_editor.png
107
- - images/url_library.png
124
+ - images/webhooks.png
108
125
  - lib/ccbill_ruby.rb
109
126
  - lib/ccbill_ruby/cli.rb
110
127
  - lib/ccbill_ruby/cli/install.rb
@@ -114,6 +131,12 @@ files:
114
131
  - lib/ccbill_ruby/dynamic_pricing.rb
115
132
  - lib/ccbill_ruby/postback.rb
116
133
  - lib/ccbill_ruby/version.rb
134
+ - responses/cancellation.json
135
+ - responses/chargeback.json
136
+ - responses/reccuring_new_sale_failure.json
137
+ - responses/reccuring_new_sale_success.json
138
+ - responses/single_new_sale_success.json
139
+ - responses/void.json
117
140
  homepage: https://github.com/DmytroVasin/ccbill_ruby/
118
141
  licenses:
119
142
  - MIT
Binary file
Binary file