※ Lagom

Lagom Callback

Once the payment is approved, the content-editor platform needs to verify the transaction. This operation is performed using a pre-shared secret, and a simple cryptographic operation.

This page details the content of the callback. If you simply want to integrate Lagom for your platform, have a look at the different implementation examples we provide.

Signature verification

The callback URL presents multiple parameters for the webserver to verify the payment integrity. Here’s an example of a callback URL, and a detailed list of the query parameters:

https://mywebsite.com/article.html?
  lgid=lgdp01SAVcm19ay4mnv5P54gf&
  lguid=lguaRjpCf7booxxLKS7XDf3eH&
  lgts=1710325447&
  lgamt=100&
  lgsig=479b491b216dea83a0bb8ce9cd3a1a222e9b5ca63abba9400fc384590f193868

The first step when receiving a callback is to verify the signature. The signature will ensure that the request is indeed coming from Lagom, and that it is aimed at a specific provider.

The signature is generated using the function below, based from the parameters above. The page relative path is also included in the signature, to ensure that the payment is only valid for this specific page.

lgsig = hmac256(secret, lguid + lgid + lgts + page_path + lgamt)

Verification model

Once the payment’s signature is validated, the platform needs to decide on a content-protection model. We propose two simple models, that offer different levels of protection.

The first model we will cover is the time based content protection, which is a simple and stateless approach to verify payments. The second model is a more involved solution based on transaction ID, that offers a stricter approach, but it also requires storing the transaction ID in a database.

Time based content protection

The time based content protection verification model is the recommended approach for simple and stateless content protection.

The time based content protection model is based on the timestamp parameter lgts. This is a simple and stateless approach, that can be implemented in a few lines of code in the content-editor platform.

// refuse timestamps that are over 10 seconds old
ts, err := strconv.Atoi(lgts)
if err != nil || int(time.Now().UTC().Unix()) > ts+10 {
  return fmt.Errorf("This link has expired")
}

This stateless approach does not require using any database. This is the solution we use in our example implementation, that runs stateless on our CDN Fastly.

Transaction ID based content protection

If tighter access-control is required, we do provide a unique transaction ID that can be stored to enforce stricter content-protection. This can be implemented by storing the lguid in a database, and checking that it has not been used before.

if database[lguid] {
  return fmt.Errorf("This link has already been used")
} else {
  database[lguid] = true
}