Google Wallet coupon and discount integration in mobile app

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Google Wallet coupon and discount integration in mobile app
Medium
from 1 business day to 3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    757
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Google Wallet Integration for Coupons and Discounts in Mobile Apps

A coupon in Google Wallet is an OfferObject on top of OfferClass. Unlike Apple Wallet where coupons are just another .pkpass type, Google Wallet separates templates (class) and instances (object). One OfferClass describes a promotion, thousands of OfferObject are personalized coupons for specific users with individual barcodes.

OfferClass: Promotion Template

def create_offer_class(campaign_id: str, title: str, discount_value: str) -> dict:
    issuer_id = "YOUR_ISSUER_ID"

    return {
        "id": f"{issuer_id}.offer_{campaign_id}",
        "issuerName": "Your Store",
        "title": title,                             # "15% discount on electronics"
        "redemptionChannel": "BOTH",                # ONLINE, INSTORE or BOTH
        "provider": "Your Store",
        "titleImage": {
            "sourceUri": {"uri": "https://yourapp.com/offer-banner.jpg"},
            "contentDescription": {
                "defaultValue": {"language": "en", "value": title}
            }
        },
        "details": f"Get {discount_value} off entire selection. Cannot be combined with other offers.",
        "finePrint": "Valid until 12/31/2024. One-time use.",
        "validTimeInterval": {
            "start": {"date": "2024-06-01T00:00:00Z"},
            "end": {"date": "2024-12-31T23:59:59Z"}
        },
        "hexBackgroundColor": "#1A73E8",
        "reviewStatus": "UNDER_REVIEW"
    }

OfferObject: Personalized Coupon

def create_offer_object(class_id: str, user_id: str, coupon_code: str) -> dict:
    issuer_id = "YOUR_ISSUER_ID"

    return {
        "id": f"{issuer_id}.coupon_{user_id}_{coupon_code}",
        "classId": class_id,
        "state": "ACTIVE",
        "barcode": {
            "type": "CODE_128",   # or QR_CODE, PDF_417
            "value": coupon_code,
            "alternateText": coupon_code
        },
        "validTimeInterval": {
            "start": {"date": "2024-06-01T00:00:00Z"},
            "end": {"date": "2024-12-31T23:59:59Z"}
        },
        "textModulesData": [
            {
                "header": "Your Promo Code",
                "body": coupon_code,
                "id": "coupon_code"
            }
        ]
    }

textModulesData displays in the lower part of the coupon — useful for a promo code that a cashier can manually enter as a backup if the scanner fails.

JWT with Coupon

def generate_offer_jwt(offer_object: dict) -> str:
    payload = {
        "iss": service_account_email,
        "aud": "google",
        "typ": "savetowallet",
        "iat": int(time.time()),
        "payload": {
            "offerObjects": [offer_object]
        }
    }
    return jwt.encode(payload, private_key, algorithm="RS256")

Android: Add Button

// Show button only if Wallet is available
walletClient.getPayApiAvailabilityStatus(
    PayApiAvailabilityStatusRequest.newBuilder()
        .setRequestType(PayApiAvailabilityStatusRequest.RequestType.SAVE_PASSES)
        .build()
).addOnSuccessListener { status ->
    binding.addCouponToWalletBtn.isVisible = status.isAvailable
}

// Add coupon
fun addCouponToWallet(jwt: String) {
    walletClient.savePassesViaIntent(
        SavePassesRequest.newBuilder().setJwt(jwt).build()
    ) { result ->
        result.intentSender?.let { sender ->
            addToWalletLauncher.launch(
                IntentSenderRequest.Builder(sender).build()
            )
        }
    }
}

Deactivating Coupon After Use

After the cashier scans the coupon, the backend should transition the object to EXPIRED:

def redeem_coupon(object_id: str):
    service = build('walletobjects', 'v1', credentials=credentials)
    service.offerobject().patch(
        resourceId=object_id,
        body={"state": "EXPIRED"}
    ).execute()

The pass in the user's Wallet automatically gets a "Used" badge without being deleted — important for purchase history.

Bulk Coupon Distribution

For distributing coupons to many users, you don't need to generate JWT for each individually when the button is clicked. You can pre-create OfferObject via REST API and store objectId in the database. The "Add to Wallet" button generates JWT with the already-created objectId — Google returns intentSender for the existing object.

Timeline

1–3 days. Promotion template + personalized coupons + deactivation — 2 days. Bulk pre-generation of objects — additionally 0.5 day. Pricing is calculated individually.