From 1263b6346034fe0b7c2c24740e114e860218aa29 Mon Sep 17 00:00:00 2001
From: Rene Vergara <rene@vergara.network>
Date: Fri, 9 Sep 2022 11:17:59 -0500
Subject: [PATCH] Implement payment recording in Xero

---
 CHANGELOG.md      |  2 ++
 src/ZGoBackend.hs | 24 +++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b00462f..3a5a3dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+- Feature to record a payment when detected on-chain
+- Function to record a payment in Xero
 - Tests for Xero account code
 - Fields in `XeroToken` for Xero payment account code
 - Support for the YWallet memo format
diff --git a/src/ZGoBackend.hs b/src/ZGoBackend.hs
index 65e3128..9c5bfc2 100644
--- a/src/ZGoBackend.hs
+++ b/src/ZGoBackend.hs
@@ -951,14 +951,36 @@ scanPayments config pipe = do
           let r = mkRegex ".*ZGo Order::([0-9a-fA-F]{24}).*"
           let k = filter (isRelevant r) txs
           let j = map (getOrderId r) k
+          mapM_ (recordPayment p (c_dbName config)) j
           mapM_ (access p master (c_dbName config) . markOrderPaid) j
-        Left e -> putStrLn $ T.unpack e
+        Left e -> print e
     getOrderId :: Text.Regex.Regex -> ZcashTx -> (String, Double)
     getOrderId re t = do
       let reg = matchAllText re (T.unpack $ zmemo t)
       if not (null reg)
         then (fst $ head reg ! 1, zamount t)
         else ("", 0)
+    recordPayment :: Pipe -> T.Text -> (String, Double) -> IO ()
+    recordPayment p dbName x = do
+      o <- access p master dbName $ findOrderById (fst x)
+      let xOrder = o >>= (cast' . Doc)
+      case xOrder of
+        Nothing -> error "Failed to retrieve order from database"
+        Just xO ->
+          unless
+            (qpaid xO && qexternalInvoice xO == "" && qtotalZec xO == snd x) $ do
+            xeroConfig <- access p master dbName findXero
+            let xC = xeroConfig >>= (cast' . Doc)
+            case xC of
+              Nothing -> error "Failed to read Xero config"
+              Just xConf -> do
+                requestXeroToken p dbName xConf "" (qaddress xO)
+                payXeroInvoice
+                  p
+                  dbName
+                  (qexternalInvoice xO)
+                  (qaddress xO)
+                  (qtotal xO)
 
 -- | RPC methods
 -- | List addresses with viewing keys loaded