Reputation: 2142
I am using the paypal-recurring gem to handle recurring payments in a Rails app. The majority of my code is from this excellent Railscast but I also want to add a payment_notification model to accept the IPN callback and store any relevant data. This Railscast goes over how to set up notifications. However, I am having a hard time figuring out how to send the paypal-recurring gem IPN callback to my PaymentNotification model.
How can I set the :ipn_url to correctly write the IPN callback to my PaymentNotification model. I tried the following so far:
1) Adding ipn_url: "http://my-app-name.com/payment_notifications"
to the process method (under options) or payment_notifications_url
2) Trying the solution suggested at the bottom of this GitHub issue page
3) Using Paypal's Instant Payment Notification (IPN) simulator to send to "http://my-app-name.com/payment_notifications", but I get an error: IPN delivery failed. HTTP error code 401: Unauthorized
EDIT
I have been able to successfully simulate the delivery of the IPN to my payments_notifications_url. Now I just need to figure out how to point the recurring gem to send the ipn to there.
Any pointers would be greatly appreciated. Below is some of my current code. If I am forgetting any relevant parts, please let me know.
PaypalPayment Model
class PaypalPayment
def initialize(subscription)
@subscription = subscription
end
def checkout_details
process :checkout_details
end
def checkout_url(options)
process(:checkout, options).checkout_url
end
def make_recurring
process :request_payment
process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now
end
def cancel_recurring
process :cancel
end
private
def process(action, options = {})
options = options.reverse_merge(
token: @subscription.paypal_payment_token,
payer_id: @subscription.paypal_customer_token,
description: @subscription.plan.name,
amount: @subscription.plan.monthly_price,
currency: "JPY"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
end
PaymentNotifications Controller
class PaymentNotificationsController < ApplicationController
protect_from_forgery :except => [:create]
def create
PaymentNotification.create!(:params => params, :status => params[:payment_status], :transaction_id => params[:txn_id])
render :nothing => true
end
end
Upvotes: 7
Views: 2740
Reputation: 2142
I got it working. In case anyone in the future runs into trouble with PayPal IPN, here are a few things I had wrong:
1) In my Subscriptions Controller I was calling if @subscription.save
instead of if @subscription.save_with_payment
so the save_with_payment method was actually never even being called.
2) In the process method I added ipn_url: "https://my-app-name.com/payment_notifications",
def process(action, options = {})
options = options.reverse_merge(
token: @subscription.paypal_payment_token,
payer_id: @subscription.paypal_customer_token,
description: @subscription.plan.name,
amount: @subscription.plan.monthly_price,
ipn_url: "https://my-app-name.com/payment_notifications",
currency: "JPY"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
3) In PayPal's developer sandbox, click on 'Test Accounts' and then click on the 'Enter Sandbox Test Site' orange button. Once there, log in with your sandbox seller credentials. Once inside go to 'My Account' and 'Profile' and under 'Selling Preferences' click on 'Instant Payment Notification Preferences'. Set your notification url to match the url you set up to receive the IPN POST and set message delivery to enabled.
Upvotes: 5