Preamble
In the era of technological development like now, online shopping is extremely developed. We can confirm that even further when the covid-19 pandemic swept, the amazone boss’s fortune has increased by 70 billion dollars. The reason is that people shop more online when isolated, but online shopping needs a reliable trading port instead of ship COD can be flipped orders can cause time and money for business people. Here I would like to introduce about gem active_merchant will help us pay a simple way. Gem is supported by shopify, an extremely large ecommerce platform, and the large developer of ecommerce CMS is Spreedly.
1. Install
Open cmd and create the project.
- Create project
1 2 | rails <span class="token keyword">new</span> <span class="token class-name">app</span> ecommerce_with_active_merchant |
- Install gem
1 2 3 4 | cd ecommerce_with_active_merchant gem install activemerchant |
- Then you remember to add the gem file offline
1 2 | gem <span class="token string">'activemerchant'</span> |
- Create a model
1 2 3 4 | rails g scaffold order <span class="token keyword">new</span> cart_id <span class="token symbol">:integer</span> ip_address <span class="token symbol">:string</span> first_name <span class="token symbol">:string</span> last_name <span class="token symbol">:string</span> card_type <span class="token symbol">:string</span> card_expires_on <span class="token symbol">:date</span> rails g model order_transaction order_id <span class="token symbol">:integer</span> action <span class="token symbol">:string</span> amount <span class="token symbol">:integer</span> success <span class="token symbol">:boolean</span> authorization <span class="token symbol">:string</span> message <span class="token symbol">:string</span> params <span class="token symbol">:text</span> |
- Config development
1 2 3 4 5 6 7 8 9 | config <span class="token punctuation">.</span> after_initialize <span class="token keyword">do</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Base</span> <span class="token punctuation">.</span> mode <span class="token operator">=</span> <span class="token symbol">:test</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">GATEWAY</span> <span class="token operator">=</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">PaypalGateway</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token punctuation">(</span> <span class="token symbol">:login</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"seller_1229899173_biz_api1.railscasts.com"</span> <span class="token punctuation">,</span> <span class="token symbol">:password</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"FXWU58S7KXFC6HBE"</span> <span class="token punctuation">,</span> <span class="token symbol">:signature</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu"</span> <span class="token punctuation">)</span> <span class="token keyword">end</span> |
- Config test
1 2 3 4 5 | config <span class="token punctuation">.</span> after_initialize <span class="token keyword">do</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Base</span> <span class="token punctuation">.</span> mode <span class="token operator">=</span> <span class="token symbol">:test</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">GATEWAY</span> <span class="token operator">=</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">BogusGateway</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token keyword">end</span> |
- Config production
1 2 3 4 5 6 7 8 9 | config <span class="token punctuation">.</span> after_initialize <span class="token keyword">do</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Base</span> <span class="token punctuation">.</span> mode <span class="token operator">=</span> <span class="token symbol">:production</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">GATEWAY</span> <span class="token operator">=</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">PaypalGateway</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token punctuation">(</span> <span class="token symbol">:login</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"seller_1229899173_biz_api1.railscasts.com"</span> <span class="token punctuation">,</span> <span class="token symbol">:password</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"FXWU58S7KXFC6HBE"</span> <span class="token punctuation">,</span> <span class="token symbol">:signature</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L-kTdszkPG8mRfjaRZDYtSu"</span> <span class="token punctuation">)</span> <span class="token keyword">end</span> |
- We add the action to create in the controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">create</span></span> <span class="token variable">@order</span> <span class="token operator">=</span> current_cart <span class="token punctuation">.</span> build_order <span class="token punctuation">(</span> params <span class="token punctuation">[</span> <span class="token symbol">:order</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token variable">@order</span> <span class="token punctuation">.</span> ip_address <span class="token operator">=</span> request <span class="token punctuation">.</span> remote_ip <span class="token keyword">if</span> <span class="token variable">@order</span> <span class="token punctuation">.</span> save <span class="token keyword">if</span> <span class="token variable">@order</span> <span class="token punctuation">.</span> purchase render <span class="token symbol">:action</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"success"</span> <span class="token keyword">else</span> render <span class="token symbol">:action</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"failure"</span> <span class="token keyword">end</span> <span class="token keyword">else</span> render <span class="token symbol">:action</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">'new'</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
- Create model cart.rb
1 2 | rails g model cart |
- Because each cart will correspond to an order, we add relation
1 2 3 4 | <span class="token keyword">class</span> <span class="token class-name">Cart</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> has_one <span class="token symbol">:order</span> <span class="token keyword">end</span> |
- Edit model order
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <span class="token keyword">class</span> <span class="token class-name">Order</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> belongs_to <span class="token symbol">:cart</span> has_many <span class="token symbol">:transactions</span> <span class="token punctuation">,</span> class_name <span class="token punctuation">:</span> <span class="token string">"OrderTransaction"</span> attr_accessor <span class="token symbol">:card_number</span> <span class="token punctuation">,</span> <span class="token symbol">:card_verification</span> validate_on_create <span class="token symbol">:validate_card</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">purchase</span></span> response <span class="token operator">=</span> <span class="token constant">GATEWAY</span> <span class="token punctuation">.</span> purchase <span class="token punctuation">(</span> price_in_cents <span class="token punctuation">,</span> credit_card <span class="token punctuation">,</span> purchase_options <span class="token punctuation">)</span> transactions <span class="token punctuation">.</span> create <span class="token operator">!</span> <span class="token punctuation">(</span> <span class="token symbol">:action</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"purchase"</span> <span class="token punctuation">,</span> <span class="token symbol">:amount</span> <span class="token operator">=</span> <span class="token operator">></span> price_in_cents <span class="token punctuation">,</span> <span class="token symbol">:response</span> <span class="token operator">=</span> <span class="token operator">></span> response <span class="token punctuation">)</span> cart <span class="token punctuation">.</span> update_attribute <span class="token punctuation">(</span> <span class="token symbol">:purchased_at</span> <span class="token punctuation">,</span> <span class="token builtin">Time</span> <span class="token punctuation">.</span> now <span class="token punctuation">)</span> <span class="token keyword">if</span> response <span class="token punctuation">.</span> success <span class="token operator">?</span> response <span class="token punctuation">.</span> success <span class="token operator">?</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">price_in_cents</span></span> <span class="token punctuation">(</span> cart <span class="token punctuation">.</span> total_price <span class="token operator">*</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> round <span class="token keyword">end</span> <span class="token keyword">private</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">purchase_options</span></span> <span class="token punctuation">{</span> <span class="token symbol">:ip</span> <span class="token operator">=</span> <span class="token operator">></span> ip_address <span class="token punctuation">,</span> <span class="token symbol">:billing_address</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token symbol">:name</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"Sun Staff"</span> <span class="token punctuation">,</span> <span class="token symbol">:address1</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"13F KNE Pham Hung street"</span> <span class="token punctuation">,</span> <span class="token symbol">:city</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"HaNoi"</span> <span class="token punctuation">,</span> <span class="token symbol">:state</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"HN"</span> <span class="token punctuation">,</span> <span class="token symbol">:country</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"VI"</span> <span class="token punctuation">,</span> <span class="token symbol">:zip</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token string">"100000"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">validate_card</span></span> <span class="token keyword">unless</span> credit_card <span class="token punctuation">.</span> valid <span class="token operator">?</span> credit_card <span class="token punctuation">.</span> errors <span class="token punctuation">.</span> full_messages <span class="token punctuation">.</span> <span class="token keyword">each</span> <span class="token keyword">do</span> <span class="token operator">|</span> message <span class="token operator">|</span> errors <span class="token punctuation">.</span> add_to_base message <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">credit_card</span></span> <span class="token variable">@credit_card</span> <span class="token operator">||</span> <span class="token operator">=</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">Billing</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">CreditCard</span> <span class="token punctuation">.</span> <span class="token keyword">new</span> <span class="token punctuation">(</span> <span class="token symbol">:type</span> <span class="token operator">=</span> <span class="token operator">></span> card_type <span class="token punctuation">,</span> <span class="token symbol">:number</span> <span class="token operator">=</span> <span class="token operator">></span> card_number <span class="token punctuation">,</span> <span class="token symbol">:verification_value</span> <span class="token operator">=</span> <span class="token operator">></span> card_verification <span class="token punctuation">,</span> <span class="token symbol">:month</span> <span class="token operator">=</span> <span class="token operator">></span> card_expires_on <span class="token punctuation">.</span> month <span class="token punctuation">,</span> <span class="token symbol">:year</span> <span class="token operator">=</span> <span class="token operator">></span> card_expires_on <span class="token punctuation">.</span> year <span class="token punctuation">,</span> <span class="token symbol">:first_name</span> <span class="token operator">=</span> <span class="token operator">></span> first_name <span class="token punctuation">,</span> <span class="token symbol">:last_name</span> <span class="token operator">=</span> <span class="token operator">></span> last_name <span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
- Transaction for order
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">class</span> <span class="token class-name">OrderTransaction</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> belongs_to <span class="token symbol">:order</span> serialize <span class="token symbol">:params</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">response</span></span> <span class="token operator">=</span> <span class="token punctuation">(</span> response <span class="token punctuation">)</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> success <span class="token operator">=</span> response <span class="token punctuation">.</span> success <span class="token operator">?</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> authorization <span class="token operator">=</span> response <span class="token punctuation">.</span> authorization <span class="token keyword">self</span> <span class="token punctuation">.</span> message <span class="token operator">=</span> response <span class="token punctuation">.</span> message <span class="token keyword">self</span> <span class="token punctuation">.</span> params <span class="token operator">=</span> response <span class="token punctuation">.</span> params <span class="token keyword">rescue</span> <span class="token constant">ActiveMerchant</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">ActiveMerchantError</span> <span class="token operator">=</span> <span class="token operator">></span> e <span class="token keyword">self</span> <span class="token punctuation">.</span> success <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> authorization <span class="token operator">=</span> <span class="token keyword">nil</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> message <span class="token operator">=</span> e <span class="token punctuation">.</span> message <span class="token keyword">self</span> <span class="token punctuation">.</span> params <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
- Edit the form to display the payment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token operator"><</span> <span class="token string">%= form_for @order do |f| %> <%=</span> f <span class="token punctuation">.</span> error_messages <span class="token string">%> <p></span> <span class="token operator"><</span> <span class="token string">%= f.label :first_name %><br /> <%=</span> f <span class="token punctuation">.</span> text_field <span class="token symbol">:first_name</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token string">%= f.label :last_name %><br /> <%=</span> f <span class="token punctuation">.</span> text_field <span class="token symbol">:last_name</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token string">%= f.label :card_type %><br /> <%=</span> f <span class="token punctuation">.</span> select <span class="token symbol">:card_type</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string">"Visa"</span> <span class="token punctuation">,</span> <span class="token string">"visa"</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string">"MasterCard"</span> <span class="token punctuation">,</span> <span class="token string">"master"</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string">"Discover"</span> <span class="token punctuation">,</span> <span class="token string">"discover"</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string">"American Express"</span> <span class="token punctuation">,</span> <span class="token string">"american_express"</span> <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token string">%= f.label :card_number %><br /> <%=</span> f <span class="token punctuation">.</span> text_field <span class="token symbol">:card_number</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token string">%= f.label :card_verification, "Card Verification Value (CVV)" %><br /> <%=</span> f <span class="token punctuation">.</span> text_field <span class="token symbol">:card_verification</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token string">%= f.label :card_expires_on %><br /> <%=</span> f <span class="token punctuation">.</span> date_select <span class="token symbol">:card_expires_on</span> <span class="token punctuation">,</span> <span class="token symbol">:discard_day</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token symbol">:start_year</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token constant">Date</span> <span class="token punctuation">.</span> today <span class="token punctuation">.</span> year <span class="token punctuation">,</span> <span class="token symbol">:end_year</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token constant">Date</span> <span class="token punctuation">.</span> today <span class="token punctuation">.</span> year <span class="token operator">+</span> <span class="token number">10</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token symbol">:add_month_numbers</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token boolean">true</span> <span class="token string">%> </p></span> <span class="token operator"><</span> p <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">%</span> <span class="token operator">=</span> f <span class="token punctuation">.</span> submit <span class="token string">"Submit"</span> <span class="token string">%></p></span> <span class="token operator"><</span> <span class="token operator">%</span> <span class="token keyword">end</span> <span class="token operator">%</span> <span class="token operator">></span> |
- Add the corresponding action and view to the order processing state
1 2 3 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">success</span></span> <span class="token punctuation">;</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">failure</span></span> <span class="token punctuation">;</span> <span class="token keyword">end</span> |
1 2 | <span class="token constant">SUCCESS</span> |
1 2 | <span class="token constant">FAILED</span> |
Mirgate database then rails s to see the results.
- create order view