Category Archives: Miscellaneous

Self hosted Gitlab and 500 error

In my case the 500 error started after migration to new server. Everything was done as per the official guide. The server started fine, the repositories, comments, issues also showed fine. The problem – on clicking a repository it showed 500 error.

Checking the error logs (under /var/log/gitlab/) didn’t reveal the problem. The best way to check Gitlab logs is to use the command –

gitlab-ctl tail

Checking the logs with the above command revealed a permission issue in these folders

drwxr-sr-x 5 git git 4096 Jul 30 22:29 /mnt/repo_storage2/git-data/repositories/+gitaly
drwxr-s--- 250 git git 4096 Jul 5 16:20 /mnt/repo_storage2/git-data/repositories/@hashed
drwxr-sr-x 9 git git 4096 Jul 17 20:18 /mnt/repo_storage2/git-data/repositories/@pools

Don’t know why/how “git-redis” became the owner of the subfolders. Changing the owner to “git” solved the 500 error.

 

 

State changes during an in-app purchase in Ionic Cordova

Here is a cleaner and summarized version of the data/state changes that are crucial for recording the transaction.

For raw dumps view this article – Ionic Cordova In-App Purchase Plugin Events Data Dumps

---------------------------------
START OF NEW PURCHASE 
---------------------------------
state:requested
canPurchase: false
owned: false

state:initiated
canPurchase: false
owned: false

state:initiated
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:finished
canPurchase: false
owned: false

AT THIS POINT - OWNED event listener is fired

"state":"owned"
"canPurchase":false
"owned":true

state:owned
canPurchase: false
owned: true


-----------------------------------------
AFTER CANCELLED AND CANCELLATION COMPLETE
-----------------------------------------
state:valid
owned:false
canPurchase:true

state:valid
owned:false
canPurchase:true


PURCHASE CANCELLED is called when the 
	Popup is cancelled
	When an expired Subscription is removed from Google Play


-----------------------------------------------------------------------------------------
WHEN THE SUBSCRIPTION IS VALID IT IS GIVING the below on screen change or app open
-----------------------------------------------------------------------------------------
state:valid
owned:false
canPurchase:true

state:valid
owned:false
canPurchase:true

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

state:approved
canPurchase: false
owned: false

AT THIS POINT - OWNED event listener is fired

state:owned
canPurchase: false
owned: true

state:owned
canPurchase: false
owned: true


The Transaction ID (GPA.3341-6605-8567-18617) changes after new purchases are made
The Purchase Token (cpfjfhlbkagpjhgcoejgmajg.AO-J1Oxa8jFURcHtEBngM5zuU...) changes after new purchases are taken. 

Please note the purchase token will remain same as long the Subscription doesn’t fail or cancelled. The subscription auto-renews and will have the same “Purchase Token“. But if the renewal fails and the grace period is over or the subscription is cancelled and re-subscribed, a new “Purchase Token” will be generated.

Ionic Cordova In-App Purchase Plugin Events Data Dumps

Below are the dumps of data received in ionic cordova app from Google billing or in-app purchase plugin events.

See this article for a summarized version – State changes during an in-app purchase in Ionic Cordova

this.store.get(my_product_id)

{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"valid","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":true,"owned":false,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":null,"transaction":null,"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true}


this.store.products

Products: [{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"valid","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":true,"owned":false,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":null,"transaction":null,"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true}]



this.store.when(my_product_id).updated((product: IAPProduct) 

Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"valid","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":true,"owned":false,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":null,"transaction":null,"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true}


AFTER THE PURCHASE INITIATED -- Not Owned or Expired

Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"requested","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":false,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":null,"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true}
login.page.ts:108 

this.store.order("com.myapp.annualsubscription2").then(async (result) 

store.Product {id: 'com.myapp.annualsubscription2', alias: 'com.myapp.annualsubscription2', type: 'paid subscription', group: 'default', state: 'initiated', …}
login.page.ts:80 

Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"initiated","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":false,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":null,"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true}


------------------------------
When already purchased and valid - if tried to purchase it will call "Updated" and the below data will be returned. Owned is true and canPurchase is false

Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"requested","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":"","oldSku":"com.myapp.annualsubscription2","oldPurchaseToken":"imggoijiflaahpaefffokpom.AO-J1OyBHUqG13A6fFZjQ2wVGo08oGFHh5ilnnwlnJ1-5dUGTEr7xt2IhejvGmuYPxNMSVyKnzcZHx93X7d0lkPgX9jOGRiSCgj2Iw7gXnYHfJ_l231h-I8"},"transaction":{"type":"android-playstore","id":"GPA.3345-8962-9923-27341","purchaseToken":"imggoijiflaahpaefffokpom.AO-J1OyBHUqG13A6fFZjQ2wVGo08oGFHh5ilnnwlnJ1-5dUGTEr7xt2IhejvGmuYPxNMSVyKnzcZHx93X7d0lkPgX9jOGRiSCgj2Iw7gXnYHfJ_l231h-I8","purchaseState":0,"receipt":"{"orderId":"GPA.3345-8962-9923-27341","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672226442183,"purchaseState":0,"purchaseToken":"imggoijiflaahpaefffokpom.AO-J1OyBHUqG13A6fFZjQ2wVGo08oGFHh5ilnnwlnJ1-5dUGTEr7xt2IhejvGmuYPxNMSVyKnzcZHx93X7d0lkPgX9jOGRiSCgj2Iw7gXnYHfJ_l231h-I8","autoRenewing":true,"acknowledged":true}","signature":"EZEp+5T/YNruAJwcJL0xBYxV9ZZDTMxM5cj3UZArlrS3F2aToJx8G7ZE7YJyl2iv99QyaLrjJGeqlFVRtUmW+zEzV/JtyYGwPdUqtatejYkZGTijFF01k/396HFJK29kE0MOV89EQr/6AncpuVjVGrP9Akg7/jdqk5LDgiQSBygT+ISZPTRBZQsQhx2rZoT+l2FabxRmxU3ojt/93bvWFKRaPVb9CNWmGkiw55E/652CDlkxbV8SzoaSRkW08vSFz3T1cKWW/BcRwLCjVdmdOHQzvm4tbUMJkHPgt+XimI7FdQBkvCRWtWujBA63Hus80hwAqseGaGzZaiaC3+WpKg=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":true,"renewalIntent":"Renew"}



AFTER PURCHASE IS DONE
---------------------------------

Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"initiated","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore"},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":true,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"approved","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":true,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"approved","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":false,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"approved","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":false,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"approved","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":false,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"finished","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":false,"renewalIntent":"Renew"}

login.page.ts:80 
Updated{"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"owned","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":{"applicationUsername":""},"transaction":{"type":"android-playstore","id":"GPA.3316-7182-4489-05118","purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","purchaseState":0,"receipt":"{"orderId":"GPA.3316-7182-4489-05118","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672228274746,"purchaseState":0,"purchaseToken":"geeofnjlooihoghajeghgfah.AO-J1Ozu_V7ScY_5aC2hM-t0sMMgERU56UNaypCX4FjJ_yGPpLAxiMbvN4oraW_iUfqlGyAiSLgbTbofrv4-81HP-AQGY_FtCAc05xLRrd2GXb31Cr3IO0o","autoRenewing":true,"acknowledged":false}","signature":"PZ/BRKILYTgVhQV8ZRe4Gxnqw9GcwSItEcreABctaMLGvNaGYLmNwM/bUHJc/C293TK4RFPJOBaGMgKD72zaOPkxeffFoe9zzh+1zRbCdCuUce4xPdsIepxhO30kIpdT+0jXoASM8U4duRGYiMcaPlBpVQOTQwtcnmjtOhHQbKtF7kosE8Mev3cpn5PTh2lPcNpio4LSuEc6akZtgXctMkkCOw5asrg8g9dUdgzavMgPc1vofcWQxU7L4XyvuQJsNW55MWNV4aMpIu6+yNJ8nfjSXRK77x130v8CtzHaN5taX7DQff5dYvtx5zcWrxjWfIJUNuuAWEwkIP3k/nCLtw=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":true,"renewalIntent":"Renew"}


this.store.order("com.myapp.annualsubscription2").then

First it is giving the OLD details //NOTE 
"state" is "initiated"
"purchaseState" is "0",
"renewalIntent" is "Lapse"
{
    "id": "com.myapp.annualsubscription2",
    "alias": "com.myapp.annualsubscription2",
    "type": "paid subscription",
    "group": "default",
    "state": "initiated",
    "title": "Annual Subscription",
    "description": "Play unlimited with an Annual Subscription",
    "priceMicros": 4000000,
    "price": "₹4.00",
    "currency": "INR",
    "countryCode": null,
    "loaded": true,
    "canPurchase": false,
    "owned": true,
    "introPrice": "",
    "introPriceMicros": "",
    "introPricePeriod": null,
    "introPriceNumberOfPeriods": null,
    "introPricePeriodUnit": null,
    "introPriceSubscriptionPeriod": null,
    "introPricePaymentMode": null,
    "ineligibleForIntroPrice": null,
    "discounts": [],
    "downloading": false,
    "downloaded": false,
    "additionalData": {
        "applicationUsername": ""
    },
    "transaction": {
        "type": "android-playstore",
        "id": "GPA.3399-8293-2056-78889",
        "purchaseToken": "gihamknkcpkdldnpbbknpopk.AO-J1Ox79aJrQexjiainR5XBKtsk-WmcJ70bhYzps1khZ6U53b91n2-U8eIKZUnOh9jZqVOcE-a12eqJtp_GowFcEaLrxMkq2b5bCzIPCQ207rFWVMPQBz8",
        "purchaseState": 0,
        "receipt": "{"orderId":"GPA.3399-8293-2056-78889","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672254433028,"purchaseState":0,"purchaseToken":"gihamknkcpkdldnpbbknpopk.AO-J1Ox79aJrQexjiainR5XBKtsk-WmcJ70bhYzps1khZ6U53b91n2-U8eIKZUnOh9jZqVOcE-a12eqJtp_GowFcEaLrxMkq2b5bCzIPCQ207rFWVMPQBz8","autoRenewing":false,"acknowledged":true}",
        "signature": "rRZXyzwlehHBYcQir2QFYiAEncB8uFPyVX5OoS2whERDS+yObqtDV4GQTZ6vSRt6NzmU1PXMXLRoWR5vW82PhZ9FlNqLvQ6Z3EYe/NfUy3xAtKE5fxpFlVxqiiJ70S9RWsN0WfDTkluj7Tp4Jkm2eH1ciHBlnxkYWkuWtxmQlL3s7DI1W/PpIDh/ao+w5IJI/H1/QJ7svZezu/Da4dtz8TZoxX7nI8sib14ryjjU40zvcDc4i5B1wdJ+SdWrByHlEsGr/ZvwR7SkXVp6Oeq0bm47uIyqu+vN6X8RM0cdtGQ08w0UeHPtHM9ssKWrYJvZS9S4lIO8IAT+tD/F7Gxc9w=="
    },
    "trialPeriod": null,
    "trialPeriodUnit": null,
    "billingPeriod": 1,
    "billingPeriodUnit": "Year",
    "valid": true,
    "acknowledged": true,
    "renewalIntent": "Lapse"
}


/////// THE AUTO RENEW KEEPS RENEWING AUTOMATICALLY -- THE PURCHASE TIME REMAINS SAME, THE ORIGINAL PURCHASE TIME. 
Owned: {"id":"com.myapp.annualsubscription2","alias":"com.myapp.annualsubscription2","type":"paid subscription","group":"default","state":"owned","title":"Annual Subscription","description":"Play unlimited with an Annual Subscription","priceMicros":4000000,"price":"₹4.00","currency":"INR","countryCode":null,"loaded":true,"canPurchase":false,"owned":true,"introPrice":"","introPriceMicros":"","introPricePeriod":null,"introPriceNumberOfPeriods":null,"introPricePeriodUnit":null,"introPriceSubscriptionPeriod":null,"introPricePaymentMode":null,"ineligibleForIntroPrice":null,"discounts":[],"downloading":false,"downloaded":false,"additionalData":null,"transaction":{"type":"android-playstore","id":"GPA.3375-4850-7157-68633","purchaseToken":"oonhpdlmpllpgdgejmamjcbl.AO-J1Ow5YVxekuyW31hJVFx0klzO40IaO3_CKwCYE41Wp-GHLPM8OcPxIM1oUcuxfVY70cldN52tT3MS79yDewB6VI6xPctTihxRKKh_os7Z9Jk7LIqm-HI","purchaseState":0,"receipt":"{"orderId":"GPA.3375-4850-7157-68633","packageName":"com.synchrodipity.psychiccircuit","productId":"com.myapp.annualsubscription2","purchaseTime":1672304595703,"purchaseState":0,"purchaseToken":"oonhpdlmpllpgdgejmamjcbl.AO-J1Ow5YVxekuyW31hJVFx0klzO40IaO3_CKwCYE41Wp-GHLPM8OcPxIM1oUcuxfVY70cldN52tT3MS79yDewB6VI6xPctTihxRKKh_os7Z9Jk7LIqm-HI","autoRenewing":true,"acknowledged":true}","signature":"HepM1z7VCy1S/faOftTsIx0RsntF4HmNPwzeY8WsoGwPyec2y9RLThCNx0zlaFcD21EGBV7ljLDCQD6WHC8WrBrzJwHqqFFZpF7JD/WbwiiWz4MbIoSIePoq8pLO8LMDEp2RDt+PquvYF8H55wqIlUiOPCxofHWU74NejI3w7xJ+k0njASpUj1lYgkA3nW+Yr5DpuK+OoYd0p3M7Ve2tR9kKpvTxfIiDL1ZIoS7cDtYm9/9RzsZakqp7CI7Y3a5dDyl1JYKLN5DQBsJhkClMavde9o6EakREWspeLqarh98xtUbff1kqdZQNEIMY8KXpYOS2bjrjQjsfP3GbT+dm5Q=="},"trialPeriod":null,"trialPeriodUnit":null,"billingPeriod":1,"billingPeriodUnit":"Year","valid":true,"acknowledged":true,"renewalIntent":"Renew"}


///ON CANCELLED 
The RENEWAL INTENT becomes : Lapse

///////////PURCHASE CANCELLED IS CALLED WHEN THE USER CANCELS THE SUBSCRIPTION POPUP


Please note the plugin doesn’t return any expiry date

Compiling Old Ionic Cordova Projects for Android API 32 and Google Billing Client 4.0

You have developed a good and nice project with Cordova a few years back and now need to publish an update then chances are you are stuck like me.

My project was just 2 years old and now while trying to update Google wanted support for API level 31 and Google Billing Client 4.0.0 at minimum. I expected this would be a piece of cake – update the Android platform and the libraries. But, no, I was welcomed by the perils of  community driven softwares with frequent core updates.

While trying to update I found that most libraries had never been updated in the past few years. And there started the first problem – library incompatibility.

After spending a lot of time in finding and troubleshooting the API level compatibility was achieved. I must mention that it was only with help of Android Studio it was possible to  understand what was going wrong. Android Studio’s logcat was more verbose and showed proper errors (Ionic cordova verbose mode was showing errors being thrown from core – and didn’t have any useful information).

And then came the second problem – the Billing library update. Which needed an update of the Purchase plugin also. Now the guide links mentioned in the plugin’s page on NPMJS takes to guides that has least to none to irrelevant information. After searching around got the actual useful guides.

And after all that I was happy that all issues are solved now time to publish the update. But no, there was more hurdles 🙂 . The splash screen icon changed back to Cordova default. That was my fault I missed the point that the splash screen policy changed. I thought – no problem – let me regenerate the splash and the icons using the cordova-res command. But the plan didn’t work  – cordova-res command didn’t generate the proper splash and icons required for Android 31+
Tried to generate through Android Studio ( https://developer.android.com/studio/write/image-asset-studio ), that generated the icons properly but it somehow broke the application (added configs in AndroidManifest which didn’t work). But I believe with a little time and analysis that could be solved.
As I was in a hurry, I created the icons manually following Google’s guide on splash ( https://developer.android.com/develop/ui/views/launch/splash-screen ) and little trial and error.
Also needed to add the below line under ‘<platform name=”android”>‘. The color needs to be what you want

<preference name="AndroidWindowSplashScreenBackground" value="#ffffff" />

Below are some of the strange issues I encountered and what I did:

First I needed to find the appropriate Cordova version that supports API level 31 and 32 and install it. Here this guide helped
https://cordova.apache.org/docs/en/11.x/guide/platforms/android/
After updating the Cordova version and other plugins. I tried to build the app but it failed. Tried building using Android Studio and found that "GradlePluginGoogleServicesVersion" need an updated version - Android Studio suggested the min version and I used that. I added the following in config.xml

<preference name="GradlePluginGoogleServicesVersion" value="4.3.14" />

also needed to do the below. Even after adding the above there were errors. Someone suggested to set that false. I did and there was no problem. 

<preference name="GradlePluginGoogleServicesEnabled" value="false" />
I needed the app to run full screen and hide the navigation bar. The internet is full of some weird solution - changing the color and transparency of the navigation bar. Albeit that didn't work. 
I tried some native codes - modifying the generated native codes in Android studio and that did work. But that was little cumbersome process. On more and more searching for a simpler and better way found this - 

Add this to config.xml
<preference name="Fullscreen" value="true" />
For the icons and the splash I did this

Created a square frame/layer of 288x288px with the same background colour as the page your loading the icon on and put your logo in the middle of this square. Your logo needs to fit within 192px or 160px as the case maybe. (https://developer.android.com/develop/ui/views/launch/splash-screen)

This website can help - https://easyappicon.com/
Was having problems with Native audio. Found that initialization at proper point is important. Initializing in the constructor and within platform.ready is working best

this.platform.ready().then(() => {

});
Talking about Native Audio - the first was I was getting the error - "Native Audio Plugin is not installed or added". But it was. 

This issue of plugin not found while the plugin is installed and added to code is due to version incompatibility. Wished the message was appropriate - the message with respect to the problem is complete haywire.
Needed to add the following to config.xml

<preference name="AndroidXEnabled" value="true" />
<preference name="enableJetifier" value="true" />
Started getting Annotation error at one point. Solved by adding the following 

ionic cordova plugin add cordova-plugin-androidx-adapter
ionic cordova plugin add cordova-plugin-androidx
After adding cordova in-app purchase plugins started getting Lint errors. Needed to add the following to build.gradle in the app folder

android {
   lintOptions {
      checkReleaseBuilds false
   }
}
This guide helped in implementing in-app purchase. But this doesn't have a direct link in the plugin page. 
https://ionicframework.com/docs/v5/native/in-app-purchase-2

This has the methods but all haven't been implemented
https://github.com/j3k0/cordova-plugin-purchase/tree/master/api
I am very thankful to Damian Tarnawsky The author of https://ionic.zendesk.com/hc/en-us/articles/7891143965975-Migrating-to-Cordova-Android-11

In summary the main things to work on

  1. Plugin versions update
  2. Appropriate Gradle and JAVA versions
  3. Appropriate Cordova and android versions
  4. Proper logo and splash sizes
  5. Appropriate entries in config.xml

And most importantly if Ionic and Cordova is throwing errors that doesn’t make sense – try building in Android Studio.

Features not Available in Self hosted Gitlab Free edition

Below is the list of features NOT available in Gitlab Free Edition. For more details visit:  https://about.gitlab.com/pricing/self-managed/feature-comparison/
https://about.gitlab.com/features/

——————————–
Source Code Management
——————————–
Required Merge Request Approvals
Restrict push and merge access
Built-in and custom project templates
Multiple approvers in code review
Approval rules for code review
Repository pull mirroring
Push rules
Block secret file push
Reject unsigned commits
Verified Committer
Instance file templates
Group file templates
Code Owners

Continue reading Features not Available in Self hosted Gitlab Free edition

Exide Battery EP Plus Series (AGM VRLA) Discharge Pattern

Exide Battery EP Plus Series (AGM VRLA) Discharge Pattern

Exide EP series batteries are sealed lead acid maintenance free battery. They use AGM (absorbed glass matt and are valve regulated). Intended to be used in Solar setup or Home UPS or inverters

As per theory of a battery, a 26 Ah battery can give 26 amps for 1 hour or 1 amp for 26 hours. But that is the ideal battery. In reality it doesn’t work that way and the time depends on discharge rate.

Here is discharge pattern for Exide EP Plus Series batteries (26Ah to 2000Ah).
Continue reading Exide Battery EP Plus Series (AGM VRLA) Discharge Pattern

SLA Battery minimum discharge voltage

Recently I installed a solar panel. I used a 12 volts Sealed Lead Acid Maintenance Free battery with it. There was a huge lot of confusion as to what to set the minimum voltage or cutoff voltage. The charge controller came with a preset of 10.8 volts. But on the internet many forums and sites suggested to keep the cutoff voltage to around 11.5, some said I can go as low as 9.0.

Confused I started going through manuals or leaflets of battery companies and understood that it better to refer to the manual or leaflet or company information than to rely on the random articles and forum posts on the internet.
Continue reading SLA Battery minimum discharge voltage

Atmega 8 pin mapping

Atmega8 to Arduino pin mapping

Here is an easy to refer mapping of Atmega 8 pins to Arduino.  Credit of this image goes to user called “System” on Arduino forum https://forum.arduino.cc/u/system/summary

The image has been taken from the post https://forum.arduino.cc/t/pwm-didnt-work-on-atmega8/248564

A neat and to the point image like this is rare on the internet. I have just put the image here as a mirror of the original to ensure availability.

Continue reading Atmega8 to Arduino pin mapping

Places Search API Call

Here is summary of how to call Places search API of Bing, Google and Here Map.

Here is little known among most developers, specially developers of India, but it is a good API and there map is also very good. Their map have internal maps (floor layout) of many buildings.

Here Maps API Call

Below is the latest v7 API, all other APIs are obsolete
Continue reading Places Search API Call