From f507981cbdfb84f55b0eebf8ed01a96fe46ed877 Mon Sep 17 00:00:00 2001 From: Mark Gregory Date: Wed, 30 Sep 2026 17:29:45 +0100 Subject: [PATCH] update to provisioner code nwew paddle code --- scripts/paddle-production-prices.sh | 222 ++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100755 scripts/paddle-production-prices.sh diff --git a/scripts/paddle-production-prices.sh b/scripts/paddle-production-prices.sh new file mode 100755 index 0000000..d540f6f --- /dev/null +++ b/scripts/paddle-production-prices.sh @@ -0,0 +1,222 @@ +#!/usr/bin/env bash + +# pdl_live_apikey_01m3sj642qagm8h0r9z6yqrgzs_3jR1damnQ1XTyA23MpmkTM_Aka + +set -euo pipefail + +# --------------------------------------------------------------------------- +# SonarDesk - Paddle Production Price Setup +# +# Creates: +# Personal Monthly +# Personal Annual +# Professional Monthly +# Professional Annual +# +# against an EXISTING Paddle production product. +# +# Usage: +# PADDLE_API_KEY="pdl_live_apikey_..." \ +# PADDLE_PRODUCT_ID="pro_..." \ +# ./scripts/paddle-production-prices.sh +# --------------------------------------------------------------------------- + +PADDLE_API_URL="https://api.paddle.com" + +: "${PADDLE_API_KEY:?PADDLE_API_KEY is required}" +: "${PADDLE_PRODUCT_ID:?PADDLE_PRODUCT_ID is required}" + +if [[ "${PADDLE_API_KEY}" != pdl_live_apikey_* ]]; then + echo "ERROR: This does not look like a Paddle LIVE API key." + echo "Refusing to continue." + exit 1 +fi + +if [[ "${PADDLE_PRODUCT_ID}" != pro_* ]]; then + echo "ERROR: PADDLE_PRODUCT_ID must start with pro_" + exit 1 +fi + +command -v curl >/dev/null 2>&1 || { + echo "ERROR: curl is required." + exit 1 +} + +command -v jq >/dev/null 2>&1 || { + echo "ERROR: jq is required." + echo "Install it on macOS with: brew install jq" + exit 1 +} + +echo +echo "============================================================" +echo " SonarDesk Paddle PRODUCTION Price Setup" +echo "============================================================" +echo +echo "API: ${PADDLE_API_URL}" +echo "Product: ${PADDLE_PRODUCT_ID}" +echo +echo "WARNING: This will create REAL Paddle production prices." +echo + +read -r -p "Continue? Type PRODUCTION to continue: " confirmation + +if [[ "${confirmation}" != "PRODUCTION" ]]; then + echo "Cancelled." + exit 0 +fi + +# --------------------------------------------------------------------------- +# Pricing +# +# Paddle unit_price amounts use the smallest currency unit: +# £9.99 = 999 +# £99.00 = 9900 +# +# Change these four values BEFORE running if required. +# --------------------------------------------------------------------------- + +CURRENCY="GBP" + +PERSONAL_MONTHLY_AMOUNT="999" +PERSONAL_ANNUAL_AMOUNT="9990" + +PROFESSIONAL_MONTHLY_AMOUNT="1999" +PROFESSIONAL_ANNUAL_AMOUNT="19990" + +create_price() { + local description="$1" + local amount="$2" + local interval="$3" + + echo + echo "Creating: ${description}" + + local payload + + payload=$(jq -n \ + --arg product_id "${PADDLE_PRODUCT_ID}" \ + --arg description "${description}" \ + --arg amount "${amount}" \ + --arg currency "${CURRENCY}" \ + --arg interval "${interval}" \ + '{ + product_id: $product_id, + description: $description, + unit_price: { + amount: $amount, + currency_code: $currency + }, + billing_cycle: { + interval: $interval, + frequency: 1 + }, + quantity: { + minimum: 1, + maximum: 1 + }, + tax_mode: "account_setting" + }' + ) + + local response + local http_code + local response_file + + response_file=$(mktemp) + + http_code=$(curl \ + --silent \ + --show-error \ + --output "${response_file}" \ + --write-out "%{http_code}" \ + --request POST \ + --url "${PADDLE_API_URL}/prices" \ + --header "Authorization: Bearer ${PADDLE_API_KEY}" \ + --header "Content-Type: application/json" \ + --header "Accept: application/json" \ + --data "${payload}") + + response=$(cat "${response_file}") + rm -f "${response_file}" + + if [[ "${http_code}" -lt 200 || "${http_code}" -ge 300 ]]; then + echo + echo "ERROR creating ${description}" + echo "HTTP ${http_code}" + echo + + echo "${response}" | jq . 2>/dev/null || echo "${response}" + + exit 1 + fi + + local price_id + + price_id=$(echo "${response}" | jq -r '.data.id // empty') + + if [[ -z "${price_id}" ]]; then + echo "ERROR: Paddle created the price but no price ID was returned." + echo "${response}" | jq . + exit 1 + fi + + echo "Created ${description}: ${price_id}" + + printf '%s' "${price_id}" +} + +echo +echo "Creating SonarDesk production prices..." +echo + +PERSONAL_MONTHLY_ID=$( + create_price \ + "SonarDesk Personal Monthly" \ + "${PERSONAL_MONTHLY_AMOUNT}" \ + "month" | tail -1 +) + +PERSONAL_ANNUAL_ID=$( + create_price \ + "SonarDesk Personal Annual" \ + "${PERSONAL_ANNUAL_AMOUNT}" \ + "year" | tail -1 +) + +PROFESSIONAL_MONTHLY_ID=$( + create_price \ + "SonarDesk Professional Monthly" \ + "${PROFESSIONAL_MONTHLY_AMOUNT}" \ + "month" | tail -1 +) + +PROFESSIONAL_ANNUAL_ID=$( + create_price \ + "SonarDesk Professional Annual" \ + "${PROFESSIONAL_ANNUAL_AMOUNT}" \ + "year" | tail -1 +) + +echo +echo +echo "============================================================" +echo " Paddle Production Prices Created" +echo "============================================================" +echo +echo "Add the following to your PRODUCTION .env:" +echo +echo "PADDLE_ENVIRONMENT=production" +echo "PADDLE_API_URL=https://api.paddle.com" +echo +echo "PADDLE_PRODUCT_ID=${PADDLE_PRODUCT_ID}" +echo +echo "PADDLE_PERSONAL_MONTHLY_PRICE_ID=${PERSONAL_MONTHLY_ID}" +echo "PADDLE_PERSONAL_ANNUAL_PRICE_ID=${PERSONAL_ANNUAL_ID}" +echo "PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID=${PROFESSIONAL_MONTHLY_ID}" +echo "PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID=${PROFESSIONAL_ANNUAL_ID}" +echo +echo "IMPORTANT:" +echo "Do not run this script again unless you intentionally want another" +echo "set of Paddle production prices." +echo