Преглед на файлове

integrated Authorize.net payment API. Fixed card number, just takes amount for now.

Harlan Iverson преди 5 години
родител
ревизия
a7099f3cda
променени са 4 файла, в които са добавени 159 реда и са изтрити 8 реда
  1. 8 1
      deps.edn
  2. 99 0
      src/pos_demo/authorize.clj
  3. 29 5
      src/pos_demo/core.clj
  4. 23 2
      src/pos_demo/core.cljs

+ 8 - 1
deps.edn

@@ -3,7 +3,14 @@
                  org.clojure/core.async {:mvn/version  "0.4.500"}
                  reagent {:mvn/version "0.8.1"}
                  ;ring {:mvn/version "1.7.1"}
-                 cljs-http {:mvn/version "0.1.46"}}        
+                 cljs-http {:mvn/version "0.1.46"}
+                 
+                 javax.xml.bind/jaxb-api {:mvn/version "2.3.0"}
+                 org.glassfish.jaxb/jaxb-runtime {:mvn/version "2.3.1"}
+                 net.authorize/anet-java-sdk {:mvn/version "LATEST"}
+                 log4j {:mvn/version "1.2.17"}
+                 
+                 }        
         
  :paths ["src" "resources"]
  :aliases {:fig {:extra-deps

+ 99 - 0
src/pos_demo/authorize.clj

@@ -0,0 +1,99 @@
+(ns pos-demo.authorize
+  
+  (:import [java.math BigDecimal RoundingMode])
+
+  (:import [net.authorize Environment])
+  (:import [net.authorize.api.contract.v1
+              MerchantAuthenticationType
+              PaymentType CreditCardType
+              TransactionRequestType
+              TransactionTypeEnum
+              CreateTransactionRequest
+              CreateTransactionResponse
+              MessageTypeEnum 
+              ARBCreateSubscriptionRequest
+              ARBCreateSubscriptionResponse
+              CreateCustomerProfileRequest
+              CreateCustomerProfileResponse
+              CustomerPaymentProfileType
+              CustomerTypeEnum
+              CustomerProfileType
+              CreateCustomerProfileRequest
+              ValidationModeEnum
+              CreateCustomerProfileResponse
+              MessageTypeEnum
+              ANetApiResponse
+            ])
+  (:import [net.authorize.api.controller.base
+             ApiOperationBase])
+  (:import [net.authorize.api.controller 
+             CreateTransactionController
+             CreateCustomerProfileController
+             ARBCreateSubscriptionController])
+             
+             
+(:import [net.authorize.api.contract.v1
+            PaymentScheduleType
+            PaymentScheduleType$Interval
+            ARBSubscriptionUnitEnum
+            ARBSubscriptionType
+            CustomerProfileIdType
+            CustomerAddressType
+  ])
+  
+  ;; 
+  (:import [javax.xml.datatype DatatypeFactory XMLGregorianCalendar])  
+  )
+
+
+(defn init [api-login-id transaction-key]
+; Common code to set for all requests
+  (ApiOperationBase/setEnvironment Environment/SANDBOX)
+  
+  (let [merchant-authentication-type (MerchantAuthenticationType.)]
+    (.setName merchant-authentication-type api-login-id)
+    (.setTransactionKey merchant-authentication-type transaction-key)
+    
+    (ApiOperationBase/setMerchantAuthentication merchant-authentication-type)
+    
+     (println "Authorize initialized.")))
+
+
+(defn create-test-payment-request [card-number card-exp amount]
+  (let [payment-type (PaymentType.)
+        credit-card (CreditCardType.)]
+        (.setCardNumber credit-card card-number)
+        (.setExpirationDate credit-card card-exp)
+        (.setCreditCard payment-type credit-card)
+        
+        (let [txn-request (TransactionRequestType.)]
+          (.setTransactionType txn-request (.value TransactionTypeEnum/AUTH_CAPTURE_TRANSACTION))
+          (.setPayment txn-request payment-type)
+          (.setAmount txn-request (BigDecimal. amount))
+          
+          txn-request)
+        
+
+))
+
+
+
+(defn send-payment-request [txn-request]
+  (let [api-request (CreateTransactionRequest.)]
+    (.setTransactionRequest api-request txn-request)
+    (let [controller (CreateTransactionController. api-request)
+          exec-result (.executeWithApiResponse controller)]
+      
+      (println "Exec result: " exec-result)
+      
+      ; is execute sync?
+      (let [response (.getApiResponse controller)]
+        (if response
+          (if (= (.getResultCode (.getMessages response)) MessageTypeEnum/OK)
+            (let [result (.getTransactionResponse response)]
+              (if (.equals (.getResponseCode result) "1")
+                (println "SUCCESS. == " (.getResponseCode result) " // " (.getAuthCode result) " // " (.getTransId result))
+                (println "Failed transaction a: " (.getResponseCode result))))
+            (println "Failed response. Code=" (.getCode (.get (.getMessage (.getMessages response)) 0))
+              "Text=" (.getText (.get (.getMessage (.getMessages response)) 0))))
+          (println "No API response."))))))

+ 29 - 5
src/pos_demo/core.clj

@@ -1,17 +1,41 @@
 (ns pos-demo.core
-  (:require [ring.middleware.resource :refer [wrap-resource]]))
+  (:require [ring.middleware.resource :refer [wrap-resource]]
+            [ring.middleware.keyword-params :refer [wrap-keyword-params]]
+            [pos-demo.authorize :as authorize]))  
   
 (defn current-date
   []
   (java.util.Date.))
 
+(defn test-authorize-payment [card-number card-exp amount]
+  (let [payment-request (authorize/create-test-payment-request card-number card-exp amount)]
+    (println "Payment request: " payment-request)
+    (let [result (authorize/send-payment-request payment-request)]
+      (println "Success! Result: " result))))
+
 (defn api-handler
   [request]
-  (when (= "/api" (:uri request))
-    {:status 200
-     :content-type "application/json"
-     :body (str "{\"msg\": \"Works. " (current-date) "\"}")}))
+  (println "request query-params keys=" (keys (:query-params request))) 
+  (cond (= "/api" (:uri request))
+        {:status 200
+         :content-type "application/json"
+         :body (str "{\"msg\": \"Works. " (current-date) "\"}")}
+         
+        (= "/pay" (:uri request))
+        (let [{:keys [amount card-number card-exp]} (:params  request)]
+          (println "Authorizing payment for amount=" amount "on card=" card-number "; expires=" card-exp)
+          (test-authorize-payment card-number card-exp amount)
+          {:status 200
+           :body "paid."
+           :content-type "text/plain"})))
+        
    
+; environmental vars and startup config options are the best way to do these.
+; these is at least one library that goes through the techniques for a given
+; variable name. We'll use yogthos/config. It is based on environ, and adds some options.
+(authorize/init "API-LOGIN-ID" "TRANSACTION-KEY") 
+ 
 (def web-handler
   (-> api-handler
+      (wrap-keyword-params)
       (wrap-resource "public")))

+ 23 - 2
src/pos_demo/core.cljs

@@ -8,7 +8,8 @@
 (enable-console-print!)
 
 (defonce app-state (atom {:shop-name "Hola world!"
-                          :active-order nil}))
+                          :active-order nil
+                          :payment-amount "0.00"}))
 
 
 ; model
@@ -75,6 +76,17 @@
         (js/alert (str "Oh, hey. Works: " (:body api-response)))
         (js/alert (str "No good :( " (:status api-response)))))))
 
+(defn pay-api
+  [amount]
+  (go
+    (let [params {:amount amount
+                  :card-number "4111111111111111"
+                  :card-exp "1022"}
+          api-response (async/<! (http/get "/pay" {:query-params params}))]
+      (if (= (:status api-response) 200)
+        (js/alert (str "Message: " (:body api-response)))
+        (js/alert (str "No good :( " (:status api-response)))))))
+
 ; UI handlers
 
 (defn new-order-clicked
@@ -98,6 +110,10 @@
   (ping-api))
 
 
+(defn pay-clicked
+  [amount]
+  (pay-api amount))
+
 (defrecord Ingredient
   [title price calories])
 
@@ -242,7 +258,12 @@
          ])
     (button "Ping API" ping-api-clicked)
    
-   
+    [:div
+      [:input#payment-amount {:type "text"
+                              :value (:payment-amount @app-state)
+                              :on-change #(swap! app-state assoc :payment-amount (-> % .-target .-value))}]
+      (button "Pay" #(pay-clicked (:payment-amount @app-state)))
+      ]
    ])