Created
April 6, 2026 06:47
-
-
Save vapvarun/e0c4cd4c507eaed9a46cc0e5c9bd813d to your computer and use it in GitHub Desktop.
How to Use the EDD REST API to Build Custom Integrations and Mobile Apps (eddsellservices.com)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * EDD REST API - API Key Authentication Example | |
| * | |
| * The EDD REST API uses a public key + secret token pair. | |
| * Generate these under Users > Your Profile > EDD API Keys. | |
| * | |
| * Authentication via query string: | |
| * https://yourstore.com/edd-api/v2/products?key=PUBLIC_KEY&token=TOKEN | |
| * | |
| * Authentication via request header (preferred for mobile apps): | |
| */ | |
| // PHP cURL example - query string auth | |
| $response = wp_remote_get( add_query_arg( [ | |
| 'key' => 'your_public_key', | |
| 'token' => 'your_secret_token', | |
| ], 'https://yourstore.com/edd-api/v2/products' ) ); | |
| $products = json_decode( wp_remote_retrieve_body( $response ), true ); | |
| // PHP cURL example - Basic Auth header (encode key:token as base64) | |
| $credentials = base64_encode( 'your_public_key:your_secret_token' ); | |
| $response = wp_remote_get( 'https://yourstore.com/edd-api/v2/products', [ | |
| 'headers' => [ | |
| 'Authorization' => 'Basic ' . $credentials, | |
| ], | |
| ] ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * EDD REST API - Fetch Products (JavaScript / React Native) | |
| * | |
| * Works in browser, Node.js, and React Native. | |
| * Uses query-string auth since mobile apps can't store server-side secrets safely. | |
| * Store credentials in a backend proxy for production apps. | |
| */ | |
| const EDD_BASE_URL = 'https://yourstore.com/edd-api/v2'; | |
| const EDD_KEY = 'your_public_key'; | |
| const EDD_TOKEN = 'your_secret_token'; | |
| async function fetchProducts( page = 1, perPage = 10 ) { | |
| const url = new URL( `${EDD_BASE_URL}/products` ); | |
| url.searchParams.set( 'key', EDD_KEY ); | |
| url.searchParams.set( 'token', EDD_TOKEN ); | |
| url.searchParams.set( 'page', page ); | |
| url.searchParams.set( 'number', perPage ); | |
| const response = await fetch( url.toString() ); | |
| if ( ! response.ok ) { | |
| throw new Error( `API error: ${response.status}` ); | |
| } | |
| return response.json(); | |
| } | |
| async function fetchSingleProduct( productId ) { | |
| const url = new URL( `${EDD_BASE_URL}/products/${productId}` ); | |
| url.searchParams.set( 'key', EDD_KEY ); | |
| url.searchParams.set( 'token', EDD_TOKEN ); | |
| const response = await fetch( url.toString() ); | |
| return response.json(); | |
| } | |
| // Usage | |
| fetchProducts( 1, 20 ).then( data => { | |
| console.log( `Total products: ${data.products.length}` ); | |
| data.products.forEach( product => { | |
| console.log( `${product.info.title} - $${product.pricing.amount}` ); | |
| }); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * EDD REST API - Register a Custom Endpoint | |
| * | |
| * Adds: GET /edd-api/v2/custom/featured-products | |
| * | |
| * Place this in your theme's functions.php or a custom plugin. | |
| */ | |
| add_action( 'edd_api_v2_query_modes', 'eddapi_register_featured_mode' ); | |
| function eddapi_register_featured_mode( $query_modes ) { | |
| $query_modes['featured-products'] = [ | |
| 'title' => 'Featured Products', | |
| 'function' => 'eddapi_get_featured_products', | |
| ]; | |
| return $query_modes; | |
| } | |
| function eddapi_get_featured_products( $data ) { | |
| // Authenticate the request | |
| if ( ! edd_api_is_valid_request( $data ) ) { | |
| return [ | |
| 'error' => [ | |
| 'error' => 'Invalid API key or token.', | |
| 'code' => 401, | |
| ], | |
| ]; | |
| } | |
| // Pull products with a custom meta flag | |
| $featured_ids = get_posts( [ | |
| 'post_type' => 'download', | |
| 'post_status' => 'publish', | |
| 'posts_per_page' => 6, | |
| 'meta_key' => '_edd_featured', | |
| 'meta_value' => '1', | |
| 'fields' => 'ids', | |
| ] ); | |
| $products = []; | |
| foreach ( $featured_ids as $id ) { | |
| $products[] = [ | |
| 'id' => $id, | |
| 'title' => get_the_title( $id ), | |
| 'price' => edd_get_download_price( $id ), | |
| 'url' => edd_get_download_file_url( null, null, $id ), | |
| 'thumb' => get_the_post_thumbnail_url( $id, 'medium' ), | |
| ]; | |
| } | |
| return [ | |
| 'featured_products' => $products, | |
| 'count' => count( $products ), | |
| ]; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * EDD REST API - Rate Limiting with Transients | |
| * | |
| * Limits each API key to 60 requests per minute. | |
| * Place in functions.php or a custom plugin. | |
| */ | |
| add_filter( 'edd_api_output_before', 'eddapi_enforce_rate_limit', 10, 3 ); | |
| function eddapi_enforce_rate_limit( $output, $query_mode, $data ) { | |
| if ( empty( $data['key'] ) ) { | |
| return $output; | |
| } | |
| $api_key = sanitize_text_field( $data['key'] ); | |
| $transient_key = 'edd_api_rate_' . md5( $api_key ); | |
| $window = 60; // seconds | |
| $max_requests = 60; // per window | |
| $current = get_transient( $transient_key ); | |
| if ( false === $current ) { | |
| set_transient( $transient_key, 1, $window ); | |
| } elseif ( (int) $current >= $max_requests ) { | |
| status_header( 429 ); | |
| wp_send_json( [ | |
| 'error' => [ | |
| 'error' => 'Rate limit exceeded. Try again in a minute.', | |
| 'code' => 429, | |
| ], | |
| ] ); | |
| exit; | |
| } else { | |
| set_transient( $transient_key, (int) $current + 1, $window ); | |
| } | |
| return $output; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * EDD REST API - Zapier Webhook on Completed Payment | |
| * | |
| * Sends purchase data to a Zapier webhook whenever a payment completes. | |
| * Replace ZAPIER_WEBHOOK_URL with your actual Zap trigger URL. | |
| */ | |
| add_action( 'edd_complete_purchase', 'eddapi_send_zapier_webhook', 10, 1 ); | |
| function eddapi_send_zapier_webhook( $payment_id ) { | |
| $payment = edd_get_payment( $payment_id ); | |
| $customer = new EDD_Customer( $payment->customer_id ); | |
| $payload = [ | |
| 'payment_id' => $payment_id, | |
| 'order_number' => $payment->number, | |
| 'customer_name' => $customer->name, | |
| 'customer_email'=> $customer->email, | |
| 'total' => $payment->total, | |
| 'currency' => $payment->currency, | |
| 'products' => array_map( function( $item ) { | |
| return [ | |
| 'name' => $item['name'], | |
| 'price' => $item['price'], | |
| 'qty' => $item['quantity'], | |
| ]; | |
| }, $payment->cart_details ), | |
| 'purchase_date' => $payment->date, | |
| 'download_urls' => edd_get_purchase_download_links( $payment_id ), | |
| ]; | |
| wp_remote_post( 'https://hooks.zapier.com/hooks/catch/YOUR_ZAPIER_WEBHOOK_URL/', [ | |
| 'method' => 'POST', | |
| 'headers' => [ 'Content-Type' => 'application/json' ], | |
| 'body' => wp_json_encode( $payload ), | |
| 'timeout' => 15, | |
| 'blocking' => false, // Fire-and-forget to avoid slowing checkout | |
| ] ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * EDD REST API - React Native Mobile Storefront (Core Logic) | |
| * | |
| * A proxy backend (Node.js / WP REST handler) stores the API credentials. | |
| * The mobile app calls YOUR proxy, not EDD directly. | |
| * This file shows the client-side data layer. | |
| */ | |
| const PROXY_BASE = 'https://api.yourstore.com/edd'; // your backend proxy | |
| class EddStoreApi { | |
| constructor( authToken ) { | |
| this.authToken = authToken; // user's app session token (NOT EDD key) | |
| } | |
| async get( path, params = {} ) { | |
| const url = new URL( `${PROXY_BASE}${path}` ); | |
| Object.entries( params ).forEach( ( [ k, v ] ) => url.searchParams.set( k, v ) ); | |
| const res = await fetch( url.toString(), { | |
| headers: { | |
| 'Authorization': `Bearer ${this.authToken}`, | |
| 'Content-Type': 'application/json', | |
| }, | |
| } ); | |
| if ( res.status === 429 ) throw new Error( 'Too many requests. Please slow down.' ); | |
| if ( ! res.ok ) throw new Error( `Request failed: ${res.status}` ); | |
| return res.json(); | |
| } | |
| // List all products | |
| getProducts( page = 1 ) { | |
| return this.get( '/products', { page, number: 20 } ); | |
| } | |
| // Get a single product with pricing tiers | |
| getProduct( id ) { | |
| return this.get( `/products/${id}` ); | |
| } | |
| // Get customer purchase history (requires authenticated user) | |
| getPurchases( email ) { | |
| return this.get( '/sales', { customer: email } ); | |
| } | |
| // Get download links for a payment | |
| getDownloads( paymentKey ) { | |
| return this.get( `/payment-receipt`, { payment_key: paymentKey } ); | |
| } | |
| } | |
| // Example: Load product catalog | |
| async function loadStorefront( api ) { | |
| const data = await api.getProducts( 1 ); | |
| return data.products.map( p => ( { | |
| id: p.info.id, | |
| title: p.info.title, | |
| price: p.pricing.amount, | |
| image: p.info.thumbnail, | |
| excerpt: p.info.excerpt, | |
| } ) ); | |
| } | |
| export default EddStoreApi; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment