Permalink
Browse files

basic flow now works

  • Loading branch information...
1 parent 802a3dd commit 73d78dea7c947306fc893e18932f8b1adc38ca51 @nov committed May 14, 2011
@@ -4,6 +4,20 @@
*= require_tree .
*/
+dl dt {
+ font-weight: bold;
+}
+dl dd {
+ margin-left: 1em;
+}
+
+div.jGrowl div.warn div.jGrowl-message {
+ color: orange;
+}
+div.jGrowl div.error div.jGrowl-message {
+ color: red;
+}
+
body > header {
position: relative;
}
@@ -12,6 +26,13 @@ body > header h1 {
font-weight: normal;
line-height: 33px;
}
+body > header a {
+ color: #333;
+ text-decoration: none;
+}
+body > header a:hover {
+ color: #666;
+}
body > header p {
color: #616161;
}
@@ -10,8 +10,8 @@
.top article {
width: 44%;
opacity: 0.6;
- margin: 1%;
- padding: 2%;
+ margin: 10px 1%;
+ padding: 10px 2%;
border: 1px solid #ddd;
border-radius: 6px;
}
@@ -33,6 +33,7 @@
@media only screen and (max-width: 767px) {
.top article {
- width: 94%;
+ width: 92%;
+ padding: 10px 4%;
}
}
@@ -1,15 +1,42 @@
class PaymentsController < ApplicationController
+ rescue_from Paypal::Exception::APIError, with: :paypal_api_error
+
+ def show
+ @payment = Payment.find_by_identifier! params[:id]
+ end
def create
payment = Payment.create! params[:payment]
payment.setup!(client)
- if params[:popup].present?
+ if payment.popup?
redirect_to payment.popup_uri
else
redirect_to payment.redirect_uri
end
end
+ def destroy
+ Payment.find_by_identifier!(params[:id]).unsubscribe!(client)
+ flash[:notice] = 'Recurring Profile Canceled'
+ redirect_to root_path
+ end
+
+ def success
+ handle_callback do |payment|
+ payment.complete!(client, params[:PayerID])
+ flash[:notice] = 'Payment Transaction Completed'
+ @redirect_uri = payment_url(payment.identifier)
+ end
+ end
+
+ def cancel
+ handle_callback do |payment|
+ payment.cancel!
+ flash[:warn] = 'Payment Request Canceled'
+ @redirect_uri = root_url
+ end
+ end
+
private
def client
@@ -19,4 +46,19 @@ def client
)
end
+ def handle_callback
+ payment = Payment.find_by_token! params[:token]
+ yield payment
+ if payment.popup?
+ render :close_flow, layout: false
+ else
+ redirect_to @redirect_uri
+ end
+ end
+
+ def paypal_api_error(e)
+ flash[:error] = e.response.details.collect(&:long_message).join('<br />')
+ redirect_to root_url
+ end
+
end
View
@@ -1,11 +1,12 @@
class Payment < ActiveRecord::Base
validates :token, uniqueness: true
validates :amount, presence: true
+ validates :identifier, uniqueness: true
scope :recurring, where(recurring: true)
scope :digital, where(digital: true)
+ scope :popup, where(popup: true)
attr_reader :redirect_uri, :popup_uri
-
def setup!(client)
response = client.setup(
payment_request,
@@ -19,24 +20,55 @@ def setup!(client)
self
end
+ def cancel!
+ self.canceled = true
+ self.save!
+ self
+ end
+
+ def complete!(client, payer_id = nil)
+ if self.recurring?
+ response = client.subscribe!(self.token, recurring_request)
+ self.identifier = response.recurring.identifier
+ else
+ response = client.checkout!(self.token, payer_id, payment_request)
+ self.payer_id = payer_id
+ self.identifier = response.payment_info.first.transaction_id
+ end
+ self.completed = true
+ self.save!
+ self
+ end
+
+ def unsubscribe!(client)
+ client.renew!(self.identifier, :Cancel)
+ self.cancel!
+ end
+
private
+ DESCRIPTION = {
+ item: 'PayPal Express Sample Item',
+ instant: 'PayPal Express Sample Instant Payment',
+ recurring: 'PayPal Express Sample Recurring Payment'
+ }
+
def payment_request
request_attributes = if self.recurring?
{
billing_type: :RecurringPayments,
- billing_agreement_description: 'Billing Agreement Description'
+ billing_agreement_description: DESCRIPTION[:recurring]
}
else
item = {
- name: 'Item Name',
- description: 'Item Description',
+ name: DESCRIPTION[:item],
+ description: DESCRIPTION[:item],
amount: self.amount
}
item[:category] = :Digital if self.digital?
{
amount: self.amount,
- description: 'Description',
+ description: DESCRIPTION[:instant],
items: [item]
}
end
@@ -46,7 +78,7 @@ def payment_request
def recurring_request
Paypal::Payment::Recurring.new(
start_date: Time.now,
- description: 'Description',
+ description: DESCRIPTION[:recurring],
billing: {
period: :Month,
frequency: 1,
@@ -1,5 +1,5 @@
<header id="masthead">
- <h1><%= t 'title' %></h1>
+ <h1><%= link_to t('title'), root_path %></h1>
<p><%= t 'description' %></p>
<div class="money">
<figure>
@@ -13,9 +13,12 @@
</head>
<body>
<%= render 'layouts/header' %>
- <%= content_tag :section, class: params.values_at(:controller, :action).join(' ') do %>
+ <%= content_tag :div, class: params.values_at(:main, :controller, :action).join(' ') do %>
<%= yield %>
<% end %>
<%= render 'layouts/footer' %>
+ <% flash.each do |theme, message| %>
+ <%= javascript_tag "$.jGrowl(#{message.to_json}, {theme: #{theme.to_json}});" %>
+ <% end %>
</body>
</html>
@@ -1,7 +1,7 @@
<%= form_for payment do |f| %>
- <%= hidden_field_tag :popup, local_assigns[:popup] %>
<%= f.hidden_field :amount %>
<%= f.hidden_field :digital %>
<%= f.hidden_field :recurring %>
+ <%= f.hidden_field :popup %>
<%= f.submit 'Pay' %>
<% end %>
@@ -1,52 +1,68 @@
-<h1><%= t 'top.title' %></h1>
-
<section>
- <h2><%= t 'payment_types.real_goods.title'%></h2>
- <p><%= t 'payment_types.real_goods.description' %></p>
- <div class="boxes">
- <article>
- <h3><%= t 'payment_types.instant.title' %></h3>
- <p><%= t 'payment_types.instant.description' %></p>
- <%= render 'payments/form', payment: Payment.new %>
- </article>
- <article>
- <h3><%= t 'payment_types.recurring.title' %></h3>
- <p><%= t 'payment_types.recurring.description' %></p>
- <%= render 'payments/form', payment: Payment.recurring.new %>
- </article>
- </div>
-</section>
+ <h1><%= t 'top.title' %></h1>
+
+ <section>
+ <h2><%= t 'payment_types.real_goods.title'%></h2>
+ <p><%= t 'payment_types.real_goods.description' %></p>
+ <div class="boxes">
+ <article>
+ <h3><%= t 'payment_types.instant.title' %></h3>
+ <p><%= t 'payment_types.instant.description' %></p>
+ <p><%= t 'payment_types.recurring.example' %></p>
+ <%= render 'payments/form', payment: Payment.new %>
+ </article>
+ <article>
+ <h3><%= t 'payment_types.recurring.title' %></h3>
+ <p><%= t 'payment_types.recurring.description' %></p>
+ <p><%= t 'payment_types.recurring.example' %></p>
+ <%= render 'payments/form', payment: Payment.recurring.new %>
+ </article>
+ </div>
+ </section>
+
+ <section>
+ <h2><%= t 'payment_types.digital_goods.title'%> (Redirect)</h2>
+ <p><%= t 'payment_types.digital_goods.description' %></p>
+ <div class="boxes">
+ <article>
+ <h3><%= t 'payment_types.instant.title' %></h3>
+ <%= render 'payments/form', payment: Payment.digital.new %>
+ </article>
+ <article>
+ <h3><%= t 'payment_types.recurring.title' %></h3>
+ <%= render 'payments/form', payment: Payment.digital.recurring.new %>
+ </article>
+ </div>
+ </section>
+
+ <section class="popup">
+ <h2><%= t 'payment_types.digital_goods.title'%> (Popup)</h2>
+ <div class="boxes">
+ <article>
+ <h3><%= t 'payment_types.instant.title' %></h3>
+ <%= render 'payments/form', payment: Payment.digital.popup.new %>
+ </article>
+ <article>
+ <h3><%= t 'payment_types.recurring.title' %></h3>
+ <%= render 'payments/form', payment: Payment.digital.popup.recurring.new %>
+ </article>
+ </div>
+ </section>
-<section>
- <h2><%= t 'payment_types.digital_goods.redirect.title'%></h2>
- <p><%= t 'payment_types.digital_goods.redirect.description' %></p>
- <div class="boxes">
- <article>
- <h3><%= t 'payment_types.instant.title' %></h3>
- <p><%= t 'payment_types.instant.description' %></p>
- <%= render 'payments/form', payment: Payment.digital.new %>
- </article>
- <article>
- <h3><%= t 'payment_types.recurring.title' %></h3>
- <p><%= t 'payment_types.recurring.description' %></p>
- <%= render 'payments/form', payment: Payment.digital.recurring.new %>
- </article>
- </div>
</section>
-<section>
- <h2><%= t 'payment_types.digital_goods.incontext.title'%></h2>
- <p><%= t 'payment_types.digital_goods.incontext.description' %></p>
- <div class="boxes">
- <article>
- <h3><%= t 'payment_types.instant.title' %></h3>
- <p><%= t 'payment_types.instant.description' %></p>
- <%= render 'payments/form', payment: Payment.digital.new, popup: true %>
- </article>
- <article>
- <h3><%= t 'payment_types.recurring.title' %></h3>
- <p><%= t 'payment_types.recurring.description' %></p>
- <%= render 'payments/form', payment: Payment.digital.recurring.new, popup: true %>
- </article>
- </div>
-</section>
+<script src="https://www.paypalobjects.com/js/external/dg.js"></script>
+<script>
+ $(function () {
+ var popup_forms = $('.popup form');
+ $.each(popup_forms, function (index, form) {
+ var sandbox = <%= Paypal.sandbox?.to_json %>;
+ var submit_id = 'paypayl_submit_' + index;
+ $('input[type=submit]', form).attr({id: submit_id});
+ flow_config = {trigger: submit_id};
+ if (sandbox) flow_config.stage = sandbox;
+ window.paypal_flows = [];
+ window.paypal_flows.push(new PAYPAL.apps.DGFlow(flow_config));
+ });
+ });
+</script>
View
@@ -4,24 +4,22 @@
en:
title: PayPal Express Sample
description: Learn how to use PayPal Express API in your Rails app.
+ top:
+ title: 'Goods & Payment Types'
payment:
- description: PayPal Express Sample Payment
+ title: Payment Details
payment_types:
instant:
title: Instant Payment
- description: About Instant Payment
+ description: Pay money and complete the transaction.
+ example: ex.) Buy a book
recurring:
title: Recurring Payment
- description: About Recurring Payment
+ description: Pay fixed amount of money every month/week.
+ example: ex.) Subscribe a magazine
real_goods:
title: Real Goods
- description: About Real Goods
+ description: Buy a real goods online. You gives your shipment address to the buyer.
digital_goods:
- redirect:
- title: Digital Goods (Redirect)
- description: About Digital Goods
- incontext:
- title: Digital Goods (Popup)
- description: About Digital Goods
- top:
- title: 'Goods & Payment Types'
+ title: Digital Goods
+ description: Buy a digital goods without disclosing your shipment address.
Oops, something went wrong.

0 comments on commit 73d78de

Please sign in to comment.