Skip to main content
Run a shop entirely inside Discord — users type /buy, get a personal checkout link, pay, and receive the product automatically via DM or role grant. Your bot owns the UX; Shoppex owns the commerce.

Why this works well

No storefront UI needed

The whole buyer journey is inside Discord — slash commands, ephemeral replies, and DMs. No website required.

Native fit for digital resellers

Gaming keys, Discord Nitro-style passes, cheat subscriptions, bot licenses — the primary audience already lives in Discord.

Flow

  1. The user runs /buy.
  2. Your bot creates a payment through the Dev API.
  3. The bot replies with a private checkout link.
  4. The buyer pays in hosted checkout.
  5. Shoppex sends your webhook.
  6. Your bot or worker grants the role or sends the key.

Shape

PieceResponsibility
Discord botSlash commands, DM delivery, role grants, user-to-order mapping
Your webhook endpointVerify signature, look up the Discord user from customer_email or custom_fields, grant role or DM the license
ShoppexCatalog, payment session creation, license pool, webhook emission

Key API calls

// When the user runs /buy
const { data: payment } = await shoppex.payments.create({
  title: product.title,
  email: userEmail,
  value: product.price,
  currency: 'USD',
  return_url: 'https://your-bot.com/return',
  custom_fields: [
    { name: 'discord_user_id', value: interaction.user.id },
    { name: 'discord_guild_id', value: interaction.guildId },
  ],
});

await interaction.reply({
  content: `Pay here: ${payment.url ?? payment.checkout_url}`,
  ephemeral: true,
});
On order:paid, read custom_fields from the payload, look up the Discord user, and deliver:
  • For a license pool (SERIALS product), the key is already in the webhook payload.
  • For a role grant, call Discord’s PUT /guilds/{guild.id}/members/{user.id}/roles/{role.id}.
  • For a recurring pass, subscribe to subscription:renewed / subscription:cancelled and adjust role state.
Use custom_fields to carry the Discord user ID and guild ID all the way through to the webhook. That way your fulfillment handler does not need a separate lookup.

Pitfalls

  • Ephemeral reply only — never post the checkout link to a public channel, or another user can pay on the buyer’s behalf.
  • Guild rate limits — role grants share Discord’s per-guild bucket. Queue role grants in a worker rather than granting synchronously from the webhook handler.
  • Rejoin logic — when a user with an active subscription rejoins the server, re-grant the role. Listen for GUILD_MEMBER_ADD and check your DB.

Architecture Reference

Setup A (pure backend webhook worker) fits best.

Licenses API

For license-pool products, /dev/v1/licenses covers validation and HWID resets.