Category Archives: PHP

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.

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

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

Firebase Web Push Browser Issue

As of today, 2nd of July 2021. FCM libraries have some bugs due to which it fails to get tokens sometimes in Chrome browsers current version.

Errors that occurs :

  1. Uncaught (in promise) FirebaseError: Messaging: A problem occured while subscribing the user to FCM: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. (messaging/token-subscribe-failed)
  2. “Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

How to integrate Firebase Push Notifications for Websites: https://www.kolkataonweb.com/code-bank/miscellaneous/website-push-notification-with-google-firebase/

 

JSON for Creating Paypal Subscription Plan

Hope this save some time for someone.

The concept is for each products there will be one or more subscription plan. End users will be presented with the Subscription plans. And they will buy the subscription.

The subscription plans can be created from both Paypal Dashboard and using REST API. Here is the REST API method.

Request URL
https://api-m.paypal.com/v1/billing/plans/

Method
Post

Header
Authorization:  Bearer A3xxxxxxxxxxr-LXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcOFiuF7__PXXXXXXXXXXXXX_YuJNIHYHGTJG
PayPal-Request-Id: TEST-REQ-ID-12345       —-  This is optional. Passing this will make consequent requests work on same initial Request. Better to omit it.

BODY

{
  "product_id": "PRODCUCT ID OF CORRESPONDING PRODUCT",
  "name": "THE NAME of Subscription Plan GOES HERE",
  "description": "THE DESCRIPTION Subscription Plan GOES HERE",
  "billing_cycles": [
    {
      "frequency": {
        "interval_unit": "MONTH",
        "interval_count": 1
      },
      "tenure_type": "REGULAR",
      "sequence": 1,    //sequence is important when there are trials. Trials will be 1 and regular packages can be 2 onwards.
      "total_cycles": 0,  // 0 means unlimited
      "pricing_scheme": {
        "fixed_price": {
          "value": "1.99",
          "currency_code": "USD"
        }
      }
    }
  ],
  "payment_preferences": {
    "auto_bill_outstanding": true,
    "setup_fee": {
      "value": "0",
      "currency_code": "USD"
    },
    "setup_fee_failure_action": "CONTINUE",
    "payment_failure_threshold": 1
  },
  "taxes": {
    "percentage": "0",
    "inclusive": false
  }
}

Return

This will return the auto-generated Plan-ID. The plan id will be needed for integration in frontend.
The Plan-ID can also be found from the Paypal Dashboard's subscription section.

 

How to get Token with Paypal Rest API

How to create products with Paypal Rest API

Paypal REST API create products

Request URL
https://api-m.paypal.com/v1/catalogs/products

Method: Post

Header
Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  // xxxxxxxxxxxxxxxx  is base64 encoded Client ID:Secret  // base64_encode(client_id_string:client_secret_string) – note the colon in between
PayPal-Request-Id:TEST-REQ-ID-12345       —-  This is optional. Passing this will make consequent requests work on same initial Request. Better to omit it.

Body

{
  "id": "YOUR OWN PRODUCT ID",
  "name": "NAME",
  "status": "ACTIVE",
  "description": "DESCRIPTION GOES HERE",
  "type":"DIGITAL", //SUITABLE TYPE
  "category":"SOFTWARE",  //SUITABLE CATEGORY
  "home_url":"YOUR WEBSITE PAGE - WHERE DETAILS OF PRODUCT IS THERE"
}

Return
The call will return the same details on success

Paypal REST API get token

Request URL
https://api-m.paypal.com/v1/oauth2/token

Method
Post

Headers
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  // xxxxxxxxxxxxxxxx  is base64 encoded Client ID:Secret  // base64_encode(client_id_string:client_secret_string) – note the colon in between

Body
grant_type:client_credentials

Return

{

"scope": "https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/disputes/read-buyer https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/disputes/read-seller https://uri.paypal.com/services/payments/refund https://api.paypal.com/v1/vault/credit-card https://api.paypal.com/v1/payments/.* https://uri.paypal.com/payments/payouts https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/subscriptions https://uri.paypal.com/services/applications/webhooks",
"access_token": "AYYYYYYYYYYWmTopNAjV__Yuk_6AP9RZWQpzxxxxxxxxxxxxxx1ifvHLHrE6RW_Zqjbieo3jcZr9999999999999999lyDA",
"token_type": "Bearer",
"app_id": "APP-XYXYXYXYXYXYCCCC",
"expires_in": 32400,
"nonce": "2021-06-18T16:42:YUKJUKJHTGTYJKHGRRFHFHFGFGBFBG-spy-N9iguUHTJbTgVjht"

}

Cross Origin or CORS Issue

We often get the CORS error when we try to run some code from localhost or XAMPP. The following steps will help to solve it. Please note you will need access to server side code or server configurations. 

  1. Set Access-Control-Allow-Origin to “*” in the code
  2. Set Header set Access-Control-Allow-Headers to “*” in the code 
  3. If the above didn’t work then add the same to .htaccess
  4. If still not solved then set the same in Apache / HTTPD configuration

In my case setting it in the code didn’t work. So it set it in the .htaccess but it also didn’t work. I was getting the error “Reason: header ‘access-control-allow-headers’ is not allowed according to header ‘Access-Control-Allow-Headers’ from CORS preflight response“. The point to note is CORS Preflight. Which indicated that the error happened before the request reached the code. So I thought to set it in Apache config and it worked.

In my case the server had ISPConfig, so I set it through ISPConfig instead of changing the actual Apache configuration file.
The configuration needs to be put under “Sites” -> “<Site Name>” ->  “Options” -> “Apache Directives”.
The exact lines to be put
Header set Access-Control-Allow-Origin “*”
Header set Access-Control-Allow-Headers “*”

 

FFMPEG Rotating Video – Transpose vs Rotate

FFMpeg can be used to rotate a video or change the video orientation. There are two ways to do that – Transpose and Rotate.

But there is a difference – with Transpose the whole video gets rotated (as is expected to happen) but with Rotate the video gets cropped to fit the existing height of the video and on the sides black border will appear.

ffmpeg -y -i INPUT.mp4 -c:v libx264 -crf 23 -acodec copy -vf "transpose=1" -metadata:s:v rotate=0 -movflags +faststart OUTPUT.mp4

transpose=1 will rotate the video clock-wise by 90 degrees.
ffmpeg -y -i INPUT.mp4 -c:v libx264 -crf 23 -acodec copy -vf "rotate=PI/2" -metadata:s:v rotate=0 -movflags +faststart OUTPUT.mp4

rotate=PI/2 will also rotate the video clock-wise by 90 degrees but the resultant video will get cropped.