Skip to main content

Django Admob server-side verification (SSV)

PyPI PyPI - Python Version PyPI - Django Version Codecov License

A Django app providing a view for handling Admob server-side verification callbacks. Successfully verified callbacks trigger a custom Django signal. Apps in your project may listen to that signal and reward the user based on the information received via the callback.

Taken from the Admob SSV documentation:

Server-side verification callbacks are URL requests, with query parameters expanded by Google, that are sent by Google to an external system to notify it that a user should be rewarded for interacting with a rewarded video ad. Rewarded video SSV (server-side verification) callbacks provide an extra layer of protection against spoofing of client-side callbacks to reward users.

Installation

pip install django-admob-ssv

Add a path for the admob_ssv.views.AdmobSSVView view to your urlpatterns.

from django.urls import path
from admob_ssv.views import AdmobSSVView


urlpatterns = [
    path('admob-ssv/', AdmobSSVView.as_view()),
]

Listen to the admob_ssv.signals.valid_admob_ssv signal and make sure you connect your receiver properly, otherwise it won't get called. Take a look at the "Where should this code live?" box.

from django.dispatch import receiver
from admob_ssv.signals import valid_admob_ssv


@receiver(valid_admob_ssv)
def reward_user(sender, query, **kwargs):
    ad_network = query.get('ad_network')
    ad_unit = query.get('ad_unit')
    custom_data = query.get('custom_data')
    # ...

Reference the official Admob SSV documentation for a list of all SSV callback parameters.

Settings

You may optionally set the following options in your Django settings.py file. The code snippet below shows the default values used.

from datetime import timedelta


ADMOB_SSV_KEY_SERVER_URL = "https://www.gstatic.com/admob/reward/verifier-keys.json",

ADMOB_SSV_KEYS_CACHE_TIMEOUT = timedelta(days=1)

ADMOB_SSV_KEYS_CACHE_KEY = "admob_ssv.public_keys"

Usage without Django signals

If you don't want to use Django signals, you may subclass the admob_ssv.views.AdmobSSVView view and override the handle_valid_ssv method.

Note that unless you call super().handle_valid_ssv(request), the admob_ssv.signals.valid_admob_ssv signal won't be sent.

from admob_ssv.views import AdmobSSVView


class MyAdmobSSVView(AdmobSSVView):
    def handle_valid_ssv(self, request) -> None:
        query = request.GET.dict()
        ad_network = query.get('ad_network')
        ad_unit = query.get('ad_unit')
        custom_data = query.get('custom_data')
        # ...

Finally add a path for your custom view to your urlpatterns.

from django.urls import path
from my_app.views import MyAdmobSSVView


urlpatterns = [
    path('admob-ssv/', MyAdmobSSVView.as_view()),
]

Using a custom ECDSA library

This project uses the ecdsa Python package to verify the signature of incoming Admob SSV callbacks.

If you want to use a different ECDSA library, you may subclass the admob_ssv.views.AdmobSSVView view and override the verify_signature method.

from admob_ssv.views import AdmobSSVView


class MyAdmobSSVView(AdmobSSVView):
    def verify_signature(
        self, public_key: str, signature: bytes, content: bytes
    ) -> bool:
        # Verify the signature using your custom ECDSA library.
        # Return True if the signature is valid, False otherwise.
        pass

Finally add a path for your custom view to your urlpatterns.

from django.urls import path
from my_app.views import MyAdmobSSVView


urlpatterns = [
    path('admob-ssv/', MyAdmobSSVView.as_view()),
]

Verify that callbacks are coming from Google

According to the AdMob SSV FAQ section one could do the following:

Use reverse DNS lookup to verify that SSV callbacks originate from Google.

Depending on your setup, possibly behind a reverse proxy, it's not trivial to determine the origin IP address of a callback.

Checking the wrong IP address could lead to callbacks being ignored. That's why we decided to leave callback origin verification up to you.

Tip: It appears to be sufficient to check whether the callback contains one of your ad unit ids, which is covered by the signature.

Example project

Take a look at our Django example project under tests/project. You can run it by executing these commands:

  1. uv sync
  2. uv run tests/project/manage.py migrate
  3. uv run tests/project/manage.py createsuperuser
  4. uv run tests/project/manage.py runserver

Live testing

The example project can be used to test Admob server-side verification live from your local machine. You may use a service like ngrok to forward requests from the internet to your local machine and the Django webserver running at port 8000.

ngrok http 127.0.0.1:8000

You are now ready to send test Admob server-side verification callbacks from the Admob console.

Object list page

Metadata

Release files for django-admob-ssv 3.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-admob-ssv 3.5.0
File Size Uploaded
django_admob_ssv-3.5.0.tar.gz 5.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-admob-ssv 3.5.0
File Interpreter ABI Platform
django_admob_ssv-3.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.3 kB

Release files / django_admob_ssv-3.5.0.tar.gz

Download URL django_admob_ssv-3.5.0.tar.gz
Size 5.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ef70b1ad5a8ec50bead7b638411b5007349f632a203f115371be4e04488b8946
BLAKE2b-256 checksum
How to use checksums
5faf322ae859bb3bd1cfde6748d0ad1ba89fd4f5b8ce3e321096f55225ddf087
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / django_admob_ssv-3.5.0-py3-none-any.whl

Download URL django_admob_ssv-3.5.0-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5bdfbdb1b48fb7d939390e27fb76b1cd97b855c54861e933fa71bc81f2dccbcd
BLAKE2b-256 checksum
How to use checksums
f81c73049f86f93c568b879a6e366d9a50495bdaa371fe05876a9cd74f038d02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

3.5.0 This release

2 release files

3.4.0

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.0

2 release files

3.0.1

2 release files

3.0.0

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.4

2 release files

1.0.3

1 release file

1.0.2

1 release file

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page