require 'spec_helper' require 'logger' ActiveMerchant::Billing::Base.mode = :test describe Killbill::PaypalExpress::PaymentPlugin do before(:each) do @plugin = Killbill::PaypalExpress::PaymentPlugin.new @plugin.conf_dir = File.expand_path(File.dirname(__FILE__) + '../../../../') logger = Logger.new(STDOUT) logger.level = Logger::DEBUG @plugin.logger = logger @plugin.start_plugin end after(:each) do @plugin.stop_plugin end it 'should be able to handle bad payment methods' do amount = BigDecimal.new("100") currency = 'USD' kb_account_id = SecureRandom.uuid kb_payment_id = SecureRandom.uuid kb_payment_method_id = SecureRandom.uuid # Create a dummy token (but never go to PayPal to validate it). This will create a dummy payment method, with no baid token = create_token(kb_account_id).token # Verify the add payment method call fails pm_kv_info = Killbill::Plugin::Model::PaymentMethodKVInfo.new pm_kv_info.key = 'token' pm_kv_info.value = token info = Killbill::Plugin::Model::PaymentMethodPlugin.new info.properties = [pm_kv_info] # Note: the call will fail because the payer_id is nil # There is another failure scenario described by https://github.com/killbill/killbill-paypal-express-plugin/issues/1 when # the CreateBillingAgreement fails. We cannot easily reproduce it though unfortunately @plugin.add_payment_method(kb_account_id, kb_payment_method_id, info).should be_false # Update the payment method (still without a baid) with a dummy kb_payment_method_id # This should never happen though payment_method = Killbill::PaypalExpress::PaypalExpressPaymentMethod.from_kb_account_id_and_token(kb_account_id, token).update_attribute(:kb_payment_method_id, kb_payment_method_id) # Attempt a payment - verify the call goes through, without throwing an exception (invalid state, but we still want PAYMENT_FAILURE, not PLUGIN_FAILURE) payment_response = @plugin.process_payment kb_account_id, kb_payment_id, kb_payment_method_id, amount, currency payment_response.status.should == :ERROR end it 'should be able to charge and refund' do @pm = create_payment_method amount = BigDecimal.new("100") currency = 'USD' kb_payment_id = SecureRandom.uuid payment_response = @plugin.process_payment @pm.kb_account_id, kb_payment_id, @pm.kb_payment_method_id, amount, currency payment_response.amount.should == amount payment_response.status.should == :PROCESSED # Verify our table directly response = Killbill::PaypalExpress::PaypalExpressResponse.find_by_api_call_and_kb_payment_id :charge, kb_payment_id response.test.should be_true response.success.should be_true response.message.should == 'Success' # Check we can retrieve the payment payment_response = @plugin.get_payment_info @pm.kb_account_id, kb_payment_id payment_response.first_payment_reference_id.should_not be_nil payment_response.amount.should == amount payment_response.status.should == :PROCESSED # Check we cannot refund an amount greater than the original charge lambda { @plugin.process_refund @pm.kb_account_id, kb_payment_id, amount + 1, currency }.should raise_error RuntimeError refund_response = @plugin.process_refund @pm.kb_account_id, kb_payment_id, amount, currency refund_response.amount.should == amount refund_response.status.should == :PROCESSED # Verify our table directly response = Killbill::PaypalExpress::PaypalExpressResponse.find_by_api_call_and_kb_payment_id :refund, kb_payment_id response.test.should be_true response.success.should be_true # Check we can retrieve the refund refund_response = @plugin.get_refund_info @pm.kb_account_id, kb_payment_id refund_response.amount.should == amount refund_response.status.should == :PROCESSED # Try another payment to verify the BAID second_amount = BigDecimal.new("94.23") second_kb_payment_id = SecureRandom.uuid payment_response = @plugin.process_payment @pm.kb_account_id, second_kb_payment_id, @pm.kb_payment_method_id, second_amount, currency payment_response.amount.should == second_amount payment_response.status.should == :PROCESSED # Check we can refund it as well refund_response = @plugin.process_refund @pm.kb_account_id, second_kb_payment_id, second_amount, currency refund_response.amount.should == second_amount refund_response.status.should == :PROCESSED # it "should be able to create and retrieve payment methods" # This should be in a separate scenario but since it's so hard to create a payment method (need manual intervention), # we can't easily delete it pms = @plugin.get_payment_methods @pm.kb_account_id, false pms.size.should == 1 pms[0].external_payment_method_id.should == @pm.paypal_express_baid pm_details = @plugin.get_payment_method_detail(@pm.kb_account_id, @pm.kb_payment_method_id) pm_details.external_payment_method_id.should == @pm.paypal_express_baid pms_found = @plugin.search_payment_methods @pm.paypal_express_baid pms_found.size.should == 1 pms_found.first.external_payment_method_id.should == pm_details.external_payment_method_id @plugin.delete_payment_method @pm.kb_account_id, @pm.kb_payment_method_id @plugin.get_payment_methods(@pm.kb_account_id, false).size.should == 0 lambda { @plugin.get_payment_method_detail(@pm.kb_account_id, @pm.kb_payment_method_id) }.should raise_error RuntimeError end private def create_token(kb_account_id) private_plugin = Killbill::PaypalExpress::PrivatePaymentPlugin.instance response = private_plugin.initiate_express_checkout kb_account_id response.success.should be_true response end def create_payment_method kb_account_id = SecureRandom.uuid # Initiate the setup process response = create_token(kb_account_id) token = response.token print "\nPlease go to #{response.to_express_checkout_url} to proceed and press any key to continue... Note: you need to log-in with a paypal sandbox account (create one here: https://developer.paypal.com/webapps/developer/applications/accounts)\n" $stdin.gets # Complete the setup process kb_payment_method_id = SecureRandom.uuid pm_kv_info = Killbill::Plugin::Model::PaymentMethodKVInfo.new pm_kv_info.key = 'token' pm_kv_info.value = token info = Killbill::Plugin::Model::PaymentMethodPlugin.new info.properties = [pm_kv_info] response = @plugin.add_payment_method kb_account_id, kb_payment_method_id, info, true response.should be_true # Verify our table directly payment_method = Killbill::PaypalExpress::PaypalExpressPaymentMethod.from_kb_account_id_and_token(kb_account_id, token) payment_method.should_not be_nil payment_method.paypal_express_payer_id.should_not be_nil payment_method.paypal_express_baid.should_not be_nil payment_method.kb_payment_method_id.should == kb_payment_method_id payment_method end end