Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tom Smith 98 posts 172 karma points
    Apr 16, 2012 @ 15:19
    Tom Smith
    0

    Custom payment provider Callback URL

    Hi All,

    I'm currently writing a custom payment provider for Google Checkout;

    Google allows you to set an API callback URL that can do one of three things. Two of these (XML api & name value pair api) are pretty useless for my needs as it requires you have a working SSL setup,

    The one that I'm using is the 'Serial Number Notification'. This 'sends a serial number notification for every order notification. This notification is not in XML format and contains the serial number as a name value pair in the POST message body. e.g. serial-number=134827144342486-00001-7'. [You can then do some handshaking with the server to get full order XML]

    Given that, I imagine the API callback URL (stored at the google end) needs to be something like;

    http://domain.whatever/tcbase/teacommerce/PaymentCallbackWithoutOrderId/GoogleCheckout/1

    However if I hit this in my browser, I get a blank XML document. Attaching to the process in visual studio gives me no activity in my public override CallbackInfo ProcessCallback(TeaCommerce.Data.Order order, HttpRequest request, Dictionary<string, string> settings) method.

    I'm getting the feeling that I've got the wrong end of the stick somewhere?

    Many Thanks,

    Tom

  • Tom Smith 98 posts 172 karma points
    Apr 16, 2012 @ 15:24
    Tom Smith
    0

    Ah can't seem to edit my post for some reason, and it's formatted the URL

    here it is again; domain.whatever/tcbase/teacommerce/PaymentCallbackWithoutOrderId/GoogleCheckout/1

     

     

  • Anders Burla 2560 posts 8256 karma points
    Apr 16, 2012 @ 16:20
    Anders Burla
    0

    Hi Tom

    Have your remembered to override the AllowCallbackWithoutOrderId and return true? Else it wont allow the server code to call this method

    Kind regards
    Anders

  • Tom Smith 98 posts 172 karma points
    Apr 16, 2012 @ 16:34
    Tom Smith
    0

    Hi Anders, 

    Yep - I have overridden that bool,

    Here's the source of my payment provider thus far,

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using TeaCommerce.Data.Payment;
    using TeaCommerce.Data;
    using umbraco.NodeFactory;
    using umbraco.BusinessLogic;
     
    namespace umbraco_extensions.teaCommerceExtensions
    {
        public class GoogleCheckoutPaymentProvider : APaymentProvider
        {
            public override bool AllowCallbackWithoutOrderId 
            { 
                get 
                    {
                        return true;
                    } 
            }
     
            public override string FormAttributes
            {
                get
                {
                    return @"name=\""GoogleCheckout\"" accept-charset=\""utf-8\"" method=\""POST\"" action=\""" + FormPostUrl + @"\"" id=\""GoogleCheckout\""";
                }
            }
     
            public override APIInfo CancelPayment(TeaCommerce.Data.Order order, Dictionary settings)
            {
                throw new NotImplementedException();
            }
     
            public override APIInfo CapturePayment(TeaCommerce.Data.Order order, Dictionary settings)
            {
                throw new NotImplementedException();
            }
     
            public override Dictionary DefaultSettings
            {
                get { 
                    Dictionary dic = new Dictionary();
                    dic.Add("merchantID", "XXXX");
                    dic.Add("merchantKey", "XXXX");
                    dic.Add("productNamePropertyAlias", "productName");
                    return dic;
                }
            }
     
            public override string FormPostUrl
            {
                get {
                    return "https://sandbox.google.com/checkout/api/checkout/v2/checkoutForm/Merchant/962632116900537";
                }
            }
     
            public override Dictionary GenerateForm(TeaCommerce.Data.Order order, string teaCommerceContinueUrl, string teaCommerceCancelUrl, string teaCommerceCallBackUrl, Dictionary settings)
            {
                Dictionary nameValues = new Dictionary();
                string productNamePropertyAlias = "";
                settings.TryGetValue("productNamePropertyAlias", out productNamePropertyAlias);
     
                //item details
                int i = 1;
                foreach (OrderLine ol in order.OrderLines)
                {
                    nameValues.Add("item_name_" + i.ToString(), ol.Properties.Single(x => x.Alias == productNamePropertyAlias).Value);
                    nameValues.Add("item_description_" + i.ToString(), (new Node(ol.NodeId)).GetProperty(Constants.productShortDescriptionPropertyAlias).Value);
                    nameValues.Add("item_quantity_" + i.ToString(), ol.Quantity.ToString());
                    nameValues.Add("item_price_" + i.ToString(), ol.UnitPriceFormattedNoSymbol);
                    nameValues.Add("item_currency_" + i.ToString(), order.Currency.ISOCode);
                    i++;
                }
     
                //shipping details
                nameValues.Add("ship_method_name_1" ,order.ShippingMethodName);
                nameValues.Add("ship_method_price_1" ,order.ShippingFeeFormattedNoSymbol);
                nameValues.Add("ship_method_currency_1" ,order.Currency.ISOCode);
                nameValues.Add("ship_method_country_1" ,order.Country.CountryCode);
     
                nameValues.Add("tax_rate", "0.0");
                nameValues.Add("tax_country", order.Country.CountryCode);
     
                nameValues.Add("edit_url", "http://" + HttpContext.Current.Request.Url.Host + (new Node(Constants.cartContentPage)).Url);
                nameValues.Add("continue_url", "http://" + HttpContext.Current.Request.Url.Host + (new Node(Constants.shopContinuePage)).Url);
     
                nameValues.Add("_charset_", "");
                return nameValues;
            }
     
            public override string GetCancelUrl(Dictionary settings)
            {
                return "http://" + HttpContext.Current.Request.Url.Host + (new Node(Constants.shopCancelPage)).Url;
            }
     
            public override string GetContinueUrl(Dictionary settings)
            {
                return "http://" + HttpContext.Current.Request.Url.Host + (new Node(Constants.shopContinuePage)).Url;
            }
     
            public override APIInfo GetStatus(TeaCommerce.Data.Order order, Dictionary settings)
            {
                throw new NotImplementedException();
            }
     
            public override CallbackInfo ProcessCallback(TeaCommerce.Data.Order order, HttpRequest request, Dictionary settings)
            {
                CallbackInfo c = new CallbackInfo("Argh, error");
                Log.Add(LogTypes.Custom,1111,"It just did something wooooo");
                return c;
            }
     
            public override APIInfo RefundPayment(TeaCommerce.Data.Order order, Dictionary settings)
            {
                throw new NotImplementedException();
            }
     
        }
    }
  • Anders Burla 2560 posts 8256 karma points
    Apr 16, 2012 @ 16:39
    Anders Burla
    0

    What is the id of your payment provider? And what is the alias? Could you get me a screenshot of the text you have in the payment providers text area in the Tea Commerce general settings?

    Kind regards
    Anders

  • Tom Smith 98 posts 172 karma points
    Apr 16, 2012 @ 17:00
    Tom Smith
    0

    Hi Anders,

    <Provider alias="GoogleCheckout" assembly="umbraco-extensions" type="umbraco_extensions.teaCommerceExtensions.GoogleCheckoutPaymentProvider" />

    How would I find the ID of the provider?
    If I look in the DB, I can see a Payment Method table that gives me
    1Credit cardGoogleCheckoutNULL111100
    So I'm assuming the ID is 1?
    Thanks,
    Tom
  • Anders Burla 2560 posts 8256 karma points
    Apr 16, 2012 @ 17:10
    Anders Burla
    0

    Yes the id is 1 and the alias also looks right.

    Have you read this post, maybe that can help you. - look for the "silent post url" - http://anders.burla.dk/umbraco/tea-commerce/using-authorize-net-with-tea-commerce/

    Are you running your project locally to debug it?

     

  • Tom Smith 98 posts 172 karma points
    Apr 16, 2012 @ 17:41
    Tom Smith
    0

    Hi Anders,

    Yep - I was using a variant of that post that I found somewhere on Our,

    I'm running the project locally, and debugging by attaching visual studio to the IIS process that that the project is running under,

    Should that web service method cause the ProcessCallback method to be hit? So if you hit the URL (domain.whatever/tcbase/teacommerce/PaymentCallbackWithoutOrderId/GoogleCheckout/1) in your browser, visual studio should pick up your breakpoints on the ProcessCallback method?

    Thanks,

    T

  • Anders Burla 2560 posts 8256 karma points
    Apr 17, 2012 @ 01:45
    Anders Burla
    0

    This is the code for the PaymentCallbackWithoutOrderId - if you run locally like domain.local/ it should attach - if not - be sure to have build as Debug and you have copied the newest bin and pdb files to your bin directory for the local website.

    public static void PaymentCallbackWithoutOrderId( string alias, long paymentMethodId ) {
          IPaymentProvider paymentProviderInstance = Base.GetPaymentProviderInstance( alias );
          if ( paymentProviderInstance.AllowCallbackWithoutOrderId ) {
            PaymentMethod paymentMethod = PaymentMethod.GetPaymentMethod( paymentMethodId );
            if ( paymentMethod != null ) {
              long? orderId = paymentProviderInstance.GetOrderId( HttpContext.Current.Request, paymentMethod.GetSettings( null ) );
    
              if ( orderId != null )
                Base.PaymentCallback( paymentProviderInstance, orderId.Value );
            }
          }
        }

    Kind regards
    Anders

  • Tom Smith 98 posts 172 karma points
    Apr 17, 2012 @ 12:48
    Tom Smith
    0

    Hi Anders,

    That's really helpful thanks.

    I imagine the orderId lookup is failing in that case which is why my PaymentCallback method isn't being hit. 

    Does anything special need to be in the Reqeust in order for it to succeed?

    Many Thanks,

    Tom

     

  • Anders Burla 2560 posts 8256 karma points
    Apr 17, 2012 @ 16:31
    Anders Burla
    1

    You would of course need to have the orderId as a post or get variable. And you would also have to have some security info so you can validate it and be sure the info is valid and secure.

    Kind regards
    Anders

  • Tom Smith 98 posts 172 karma points
    Apr 17, 2012 @ 17:13
    Tom Smith
    0

    Hi Anders,

    OK in that case, I will need to write my own version of the PaymentCallbackWithoutOrderId method as I need to do some handshaking with the google server before I can get the orderId that the callback request relates to,

    Initial issues with this seem to be that the GetPaymentProviderInstance method doesn't appear to exist within TeaCommerce.Base? And Base.PaymentCallback is looking for two string parameters rather than an IPaymentProvider and a long,

    Could this be due to the tea commerce version that I'm running? 

    That's proabalby only an accademic question as my new method will only work with / be called by google so I can just code as google needs :)

    Thanks,

    Tom

  • Tom Smith 98 posts 172 karma points
    Apr 17, 2012 @ 17:24
    Tom Smith
    0

    Hi Anders,

    I'm being a massive spanner,

    I had forgotten to public override long? GetOrderId(HttpRequest request, Dictionary<string, string> settings)

    All working as expected now! 
    Thanks for all your help - I understand TeaCommerce much better now!
    Tom
Please Sign in or register to post replies

Write your reply to:

Draft