Skip to content

Instantly share code, notes, and snippets.

@abhianair
Last active August 18, 2023 11:36
Show Gist options
  • Save abhianair/3f5143be8d090966126b4a87d6fea6c9 to your computer and use it in GitHub Desktop.
Save abhianair/3f5143be8d090966126b4a87d6fea6c9 to your computer and use it in GitHub Desktop.
Paypal creating subscription using paypal api with ruby on rails
require 'net/http'
require 'uri'
def create
@subscription = current_user.subscriptions.build(subscription_params)
if @subscription.save
create_subscription_with_api(@subscription)
else
redirect_to request.referrer, notice: 'Some error caused in the payment gateway.'
end
end
def create_subscription_with_api(subscription)
token = get_app_access_token
remove_and_cancel_subscriptions(subscription, token)
redirect_to_payment_path(token, subscription)
end
def get_app_access_token
client_id = "#{Rails.application.secrets.paypal_client_id}"
client_secret = "#{Rails.application.secrets.paypal_client_secret}"
uri = URI.parse("#{Rails.application.secrets.paypal_api}/v1/oauth2/token")
request = Net::HTTP::Post.new(uri)
request.basic_auth(client_id, client_secret)
request["Accept"] = "application/json"
request["Accept-Language"] = "en_US"
request.set_form_data(
"grant_type" => "client_credentials",
)
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
response_body = ActiveSupport::JSON.decode(response.body)
return response_body['access_token']
end
def remove_and_cancel_subscriptions(subscription, token)
active_subs = subscription.user.subscriptions.where(:active => true)
if active_subs.present?
active_subs.each do |sub|
deactivate_subscriptions(token, sub)
end
end
return
end
def deactivate_subscriptions(token, sub)
uri = URI.parse("#{Rails.application.secrets.paypal_api}/v1/billing/subscriptions/#{sub.sub_id}/cancel")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer #{token}"
request.body = JSON.dump({
"reason" => "Not satisfied with the service"
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
sub.update_attributes(:active => false, :status => 'DEACTIVATED') #deactivate this
sub.user.update_attributes paid: false
end
def redirect_to_payment_path(token, subscription)
uri = URI.parse("#{Rails.application.secrets.paypal_api}/v1/billing/subscriptions")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer #{token}"
request["Paypal-Request-Id"] = "SUBSCRIPTION-21092020-001"
request.body = JSON.dump({
"plan_id" => "#{subscription.plan.paypal_plan_id}",
"subscriber" => {
"name" => {
"given_name" => "John",
"surname" => "Doe"
},
"email_address" => "[email protected]",
},
"application_context" => {
"brand_name" => "DocHours",
"locale" => "en-US",
"shipping_preference" => "SET_PROVIDED_ADDRESS",
"user_action" => "SUBSCRIBE_NOW",
"payment_method" => {
"payer_selected" => "PAYPAL",
"payee_preferred" => "IMMEDIATE_PAYMENT_REQUIRED"
},
"return_url" => "#{Rails.application.secrets.app_host}#{subscription_path(subscription)}",
"cancel_url" => "#{Rails.application.secrets.app_host}#{settings_path}"
}
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
response_body = ActiveSupport::JSON.decode(response.body)
if response_body['status'] == 'APPROVAL_PENDING'
redirect_path = response_body['links'][0]['href']
redirect_to redirect_path
else
redirect_to request.referrer, notice: "Some error caused in payment gateway"
end
end
# webhook for cancel subscription
def canceled_from_paypal
sub_id = params['resource']['id']
subs = Subscription.where(:sub_id => sub_id).last
subs.user.subscriptions.update_all(:active => false, :status => 'DEACTIVATED')
subs.user.update_attributes(:paid => false)
end
# webhook for renewal
def subscription_paypal_renewed
subscription = params[:resource][:id]
plan = params[:resource][:plan_id]
next_billing_time = params[:resource][:billing_info][:next_billing_time].to_datetime
end
# get trasaction details of subscriptions
def get_transactions
started_at = current_user.created_at
end_at = DateTime.now
p started_at
token = get_app_access_token
current_user.subscriptions.each_with_index do |sub, index|
uri = URI.parse("#{Rails.application.secrets.paypal_api}/v1/billing/subscriptions/#{sub.sub_id}/transactions?start_time=#{started_at.strftime('%Y-%m-%d')}T00:00:00.940Z&end_time=#{end_at.strftime('%Y-%m-%d')}T07:50:20.940Z")
request = Net::HTTP::Get.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer #{token}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
p '========================'
response_json = ActiveSupport::JSON.decode(response.body)
end
return
# redirect_to request.referrer, notice: 'redirected'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment