7.1 Payment Framework

The Limax provides the complete payment framework, and could access any third party payment system. Meanwhile, this payment framework isolates the third party payment system and the implementation of the application server for the development debug of the application server.


  • A class payment process

    1. The Provider releases the product information to the Endpoint (optional)

    2. The Endpoint makes order to the Auany, obtains the order id, and initiates the payment to the third party payment system by using this order id.

    3. The third party payment system sends the payment result to the Auany. If the payment fails, the process ends.

    4. The Auany deliveries the payment data to the application server.


  • B class payment process

    1. The Endpoint purchases from the payment server, and obtains the receipt.

    2. The Endpoint submits the receipt to the Auany till the Auany accepts the receipt.

    3. The Auany verifies the receipt from the server. If fails, the process ends.

    4. The Auany deliveries the payment data to the application server.


  • The Client


    limax.Endpoint.AuanyService.pay(int gateway, int payid, int product, int price, int quantity, String receipt, long timeout,Result onresult);
    

    This method initiates the payment to the Auany.

    gateway:the id assigned by the system for the third party payment gateway which will be used next.

    payid:the ProviderId which accepts the payment within the system. After the third party payment gateway successfully pay, the Auany uses this ProviderId to post.

    product:the product numbe

    price:cost per unit

    quantity:sum

    recepit:receipt

    timeout:the timeout for the request, and Milliseconds is the unit

    onresult:accept the return result


    public interface ResultPay {
        void accept(int errorSource, int errorCode, String result);
    }
    

    Please pay attentation to that the A class payment process firstly calles the pay, verifies errorCode == 0, obtains the result, and initiates the third party payment by using result immediately; the B class payment process obtains the receipt, stores the receipt locally, calles the pay by using the receipt, after returning the errorCode == 0 the local storaged receipt could be deleted, or should continue re-try.


  • Provider

    • Implementation


      public interface PaySupport {
          void onPay(long serial, long sessionid, int product, int price, int quantity, Runnable ack);
          void onPayConfirm(long serial, Runnable ack);
      }
      

      The Provider implements the PaySupport interface when it implments the ProviderListener.

      Firstly it needs to provide a table to record serial.


      The implementation of the onPay.

      1. Check whether the serial existes in the table. If existes, go to step #4.

      2. Check whether the product and price match the product information in the system definition. If they do not match, it means that there is fraud when the Endpoint initiates the payment to the Auany. For the B class payment preice=-1, it only needs to check the product. At this time, this income could be handled according to the application design requirment, then go to step #4.

      3. Provide the products to the user corresponding to the sessionid, the product sum is the quantity, and record the serial. These two operations should be implemented in one transaction.

      4. Call ack();


      The implementation of the onPayConfirm

      1. Delete the serial recorded in the table

      2. Call ack();


      Please pay attentation to that these two methods should call the ack in the final of the operations. If the ack is not called, the Auany will initiates the request to the Provider periodly. When recording the payment log, the Long.toString(serial, Character.MAX_RADIX) is used to obtain the order number. This order number corresponds to the payment log of the Auany so that the reconciliation is easily proceeded when necessary.


    • Configuration

      There is no any configuration demanded by the Provider.


  • The configuration of the Auany

    • The attribute of the Auany configuration element

      payEnable:enable the payment support of the operating environment. The default value is true.

      payLoggerClass:the implementation class of the payment log. The default values is limax.auany.PayLoggerSimpleFile. The own payment log class of the operating environment itself could be defined, and this class must implent the limax.auany.payLogger interface.

      payLoggerSimpleFileHome:the directory used by the PayLoggerSimpleFile when recording the payment log. The default values is paylogs.

      orderExpire:the expire time of the order. The default value is 3600000ms which means 1 hour.

      orderQueueConcurrencyBits:the concurrency paramenters of the order process queue. The default value is 3. 1<<3==8 process queue could be created.

      orderQueueHome:the directory of the order process queue. The default value is queue.

      deliveryExpire:the expire time of the order delivery. The default value is 604800000ms which means 7 days. There are some reasons for delivery expire. First, the payid prvoided when making order is wrong. Second, the Provider corresponding to the payid has never been enabled in the expire period. Third, when the application implements the limax.Provider.PaySupport, the ack() is not called. After the order delivery expire, the PayLogger.logDead is called.

      deliveryQueueCheckPeriod:the check period of the delivery queue. The default value is 60000ms which means 1 minute.

      deliveryQueueBackoffMax:the backoff parameter of the delivery failure. The default value is 5. The backoff period serial 1,2,3,4,5,5,5... is defined. The 1,2,3,4,5 here is used to multiply deliveryQueueCheckPeriod as the next check delay.

      deliveryQueueConcurrencyBits:the concurrency parameter of the delivery queue. The default value is 3. The 1<<3 == 8 process queue is created.

      deliveryQueueHome:the process directory of the delivery queue. The default value is queue.


    • The attribute of the pay configuration element

      gateway:the id assigned by the operating system for the third party payment gateway

      className:the message process class of the third party payment gateway. The limax.auany.PayGateway interface must be implemented.


  • The extension of the third party payment gateway


    public interface PayGateway {
        void initialize(Element e, Map<String, HttpHandler> httphandlers) throws Exception;
        void unInitialize();
        void onPay(long sessionid, int gateway, int payid, int product, int price, int quantity, String receipt,Result onresult) throws Exception;
    }
    

    The initialize method initiates the configuration of the third party payment gateway. Generally, the third party payment gateway uses http to delivery the payment message, and sets the link between the own httpContext and httpHandler in the httphandlers.

    The onPay method implements the detailed payment operation.

    • A class payment example

      The system provides the limax.auany.paygws.Simulation to simulate the payment gateway. The developer could imitate this implementation to extend more support to the third party payment gateway. This simulation payment gateway could be used for application debug. The default configuration is below:


      <pay className="limax.auany.paygws.Simulation" gateway="0" httpContext="/pay/simulation" maxAmount="999999" maxDeliveryRandomDelay="30000"/>
      

      two debug way:

      1. Access http://auanyserver:8181/pay/simulation?<order> via http. The order is the order number returned for the customer's payment operation. This way only support the success payment.

      2. In the condition of maxDeliveryRandomDelay > 0, the system randoms a delay in the range prescribed by maxDeliveryRandomDelay, then processes the result delivery. If the price * quantity is in the {0, maxAmount} range, the payment success, or fail. The maxDeliveryRandomDelay == 0 only supports the http way.


    • B class payment example

      The system provides limax.auany.paygws.AppStore to support the payment of the AppStore. The default configuration is below.


      <appstore connectTimeout="15000" home="appstore"
                  readTimeout="15000" receiptExpire="604800000"
                  receiptReplayProtectorConcurrentBits="3"
                  receiptVerifyScheduler="4" retryDelay="300000"/>
      <pay className="limax.auany.paygws.AppStore" gateway="1"
                  productPattern="[^\d]+([\d]+)$" url="https://buy.itunes.apple.com/verifyReceipt"/>
      

      The appstore element here is the global configuration of the appstore service.

      connectTimeout:connection to the receipt verification service timeout, the default value is 15000ms

      readTimeout:the return result of the receipt verification server timeout, the default value is 15000ms

      retryDelay:the next scheduling delay after the failure of the accessing the receipt verification server, the default value is 300000ms which means 5 minutes

      receiptVerifyScheduler:the thread sum of the receipt verification scheduler, the default value is 4

      home:the root directory of the files relative to the appstore, the default directory is the appstore directory in the current directory

      receiptExpire:the receipt expire, the system rejects to accept the old overdue receipt, beginning from the payment date of the receipt. The default value is 604800000ms which stands for 7 days.

      receiptReplayProtectorConcurrentBits:the concurrency parameters of the receipt replay protector, the default value is 3 which means that 1<<3==8 threads are allowed to verify the replay at the same time

      Please pay attention to that all the B class payment has the receipt replay issue. Although the implementation requires that the local storage should be proceeded before the client to verify the receipt, after the server shipment completes and notifies the client, the client deletes the locally stored receipt, this solution itself is not reliable and could not avoid the deception from some malicious programs when they deletes the local receipt for the receipt replay. To resolve this issue, the receipt timeout is necessary. The replay protection is proceeded within this time and fails immediately exceeding this time. So the storage sum of the replay protecation is bounded.


      Except for the gateway and className attributes in the pay element:

      productPattern:regular expression to match the product-id in the receipt. The system directly reject if none-match. The parsed number corresponding to the group(1) which matches the result is deliveried as the product paramter of this framework.

      url:the url of the receipt verification server


Prev Next