{"id":363631,"date":"2026-09-06T18:38:17","date_gmt":"2026-09-06T18:38:17","guid":{"rendered":"https:\/\/fr.wordpress.org\/plugins\/sprint-connect-for-helloasso\/"},"modified":"2026-09-06T18:37:42","modified_gmt":"2026-09-06T18:37:42","slug":"sprint-connect-for-helloasso","status":"publish","type":"plugin","link":"https:\/\/da.wordpress.org\/plugins\/sprint-connect-for-helloasso\/","author":23539978,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Sprint Connect for HelloAsso","header_author":"Sprint Plugins","header_description":"Universal HelloAsso connector for WordPress: forms, orders, items, participants, payers and payments, with manual import and an optional Pro extension.","assets_banners_color":"eaeffc","last_updated":"2026-09-06 18:37:42","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/sprintplugins.fr\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":59,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sprintplugins","date":"2026-09-06 18:37:42","revision":3683821}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3683842,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3683842,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3683842,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500-fr.png":{"filename":"banner-1544x500-fr.png","revision":3683842,"resolution":"1544x500","location":"assets","locale":"fr","width":1544,"height":500},"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3683842,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250-fr.png":{"filename":"banner-772x250-fr.png","revision":3683842,"resolution":"772x250","location":"assets","locale":"fr","width":772,"height":250},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3683842,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3688138,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=sprint-connect-for-helloasso#forms\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"features\":{\"networking\":false},\"siteOptions\":{\"blogname\":\"Sprint Connect for HelloAsso \\u2014 Playground\",\"blogdescription\":\"Sprint Connect for HelloAsso \\u2014 WordPress.org Playground preview\"},\"steps\":[{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"sprint-connect-for-helloasso\"},\"options\":{\"activate\":true}},{\"step\":\"mkdir\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\"},{\"step\":\"writeFile\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\\\/scha-playground-demo.php\",\"data\":\"<?php\\n\\\/**\\n * Sprint Connect for HelloAsso - WordPress.org Playground demo helper.\\n * Synthetic data only. Loaded only inside the Playground created by blueprint.json.\\n *\\\/\\ndefined('ABSPATH') || exit;\\n\\nif (!defined('SCHA_DISABLE_NETWORK_DELAYS')) {\\n    define('SCHA_DISABLE_NETWORK_DELAYS', true);\\n}\\n\\n\\n\\\/**\\n * Adapt demo-facing copy to the locale selected by WordPress.org Playground.\\n * Technical HelloAsso identifiers remain unchanged.\\n *\\\/\\nfunction scha_pg_is_fr() {\\n    $locale = function_exists('determine_locale') ? determine_locale() : get_locale();\\n    $locale = strtolower(str_replace('-', '_', (string) $locale));\\n    return $locale === 'fr' || strpos($locale, 'fr_') === 0;\\n}\\n\\nfunction scha_pg_text($english, $french) {\\n    return scha_pg_is_fr() ? $french : $english;\\n}\\n\\nfunction scha_pg_catalog() {\\n    static $forms = null;\\n    if ($forms !== null) return $forms;\\n    $catalog_json = scha_pg_is_fr() ? '[{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"adult-membership-2026\\\",\\\"title\\\":\\\"Adh\\u00e9sion adulte 2026\\\",\\\"tier\\\":\\\"Adh\\u00e9sion adulte\\\",\\\"amount\\\":4500,\\\"id\\\":10001},{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"family-membership-2026\\\",\\\"title\\\":\\\"Adh\\u00e9sion famille 2026\\\",\\\"tier\\\":\\\"Adh\\u00e9sion famille\\\",\\\"amount\\\":8500,\\\"id\\\":10002},{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"youth-license-2026\\\",\\\"title\\\":\\\"Licence jeune 2026\\\",\\\"tier\\\":\\\"Licence jeune\\\",\\\"amount\\\":3000,\\\"id\\\":10003},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"autumn-tournament-2026\\\",\\\"title\\\":\\\"Tournoi d\\u2019automne 2026\\\",\\\"tier\\\":\\\"Billet de tournoi\\\",\\\"amount\\\":1500,\\\"id\\\":10004},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"annual-gala-2026\\\",\\\"title\\\":\\\"Gala annuel 2026\\\",\\\"tier\\\":\\\"Billet du gala\\\",\\\"amount\\\":3500,\\\"id\\\":10005},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"discovery-workshop-2026\\\",\\\"title\\\":\\\"Atelier d\\u00e9couverte 2026\\\",\\\"tier\\\":\\\"Inscription \\u00e0 l\\u2019atelier\\\",\\\"amount\\\":2000,\\\"id\\\":10006},{\\\"type\\\":\\\"Donation\\\",\\\"slug\\\":\\\"free-donations-2026\\\",\\\"title\\\":\\\"Dons libres 2026\\\",\\\"tier\\\":\\\"Don\\\",\\\"amount\\\":2500,\\\"id\\\":10007},{\\\"type\\\":\\\"Donation\\\",\\\"slug\\\":\\\"equipment-support-2026\\\",\\\"title\\\":\\\"Soutien au mat\\u00e9riel 2026\\\",\\\"tier\\\":\\\"Don pour le mat\\u00e9riel\\\",\\\"amount\\\":4000,\\\"id\\\":10008},{\\\"type\\\":\\\"CrowdFunding\\\",\\\"slug\\\":\\\"community-minibus-2026\\\",\\\"title\\\":\\\"Projet de minibus associatif\\\",\\\"tier\\\":\\\"Contribution au projet\\\",\\\"amount\\\":5000,\\\"id\\\":10009},{\\\"type\\\":\\\"CrowdFunding\\\",\\\"slug\\\":\\\"training-room-2026\\\",\\\"title\\\":\\\"Projet de nouvelle salle d\\u2019entra\\u00eenement\\\",\\\"tier\\\":\\\"Contribution au projet\\\",\\\"amount\\\":7500,\\\"id\\\":10010},{\\\"type\\\":\\\"Shop\\\",\\\"slug\\\":\\\"club-shop-2026\\\",\\\"title\\\":\\\"Boutique du club 2026\\\",\\\"tier\\\":\\\"T-shirt du club\\\",\\\"amount\\\":2000,\\\"id\\\":10011},{\\\"type\\\":\\\"Shop\\\",\\\"slug\\\":\\\"equipment-shop-2026\\\",\\\"title\\\":\\\"Boutique de mat\\u00e9riel 2026\\\",\\\"tier\\\":\\\"Pack de mat\\u00e9riel\\\",\\\"amount\\\":6000,\\\"id\\\":10012},{\\\"type\\\":\\\"PaymentForm\\\",\\\"slug\\\":\\\"workshop-balance-2026\\\",\\\"title\\\":\\\"Solde de l\\u2019atelier 2026\\\",\\\"tier\\\":\\\"Solde de l\\u2019atelier\\\",\\\"amount\\\":8000,\\\"id\\\":10013},{\\\"type\\\":\\\"PaymentForm\\\",\\\"slug\\\":\\\"trip-contribution-2026\\\",\\\"title\\\":\\\"Participation au voyage 2026\\\",\\\"tier\\\":\\\"Participation au voyage\\\",\\\"amount\\\":5500,\\\"id\\\":10014},{\\\"type\\\":\\\"Checkout\\\",\\\"slug\\\":\\\"membership-supplement-2026\\\",\\\"title\\\":\\\"Compl\\u00e9ment d\\u2019adh\\u00e9sion\\\",\\\"tier\\\":\\\"Compl\\u00e9ment d\\u2019adh\\u00e9sion\\\",\\\"amount\\\":1200,\\\"id\\\":10015},{\\\"type\\\":\\\"Checkout\\\",\\\"slug\\\":\\\"exceptional-contribution-2026\\\",\\\"title\\\":\\\"Contribution exceptionnelle\\\",\\\"tier\\\":\\\"Contribution exceptionnelle\\\",\\\"amount\\\":2500,\\\"id\\\":10016}]' : '[{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"adult-membership-2026\\\",\\\"title\\\":\\\"Adult membership 2026\\\",\\\"tier\\\":\\\"Adult membership\\\",\\\"amount\\\":4500,\\\"id\\\":10001},{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"family-membership-2026\\\",\\\"title\\\":\\\"Family membership 2026\\\",\\\"tier\\\":\\\"Family membership\\\",\\\"amount\\\":8500,\\\"id\\\":10002},{\\\"type\\\":\\\"Membership\\\",\\\"slug\\\":\\\"youth-license-2026\\\",\\\"title\\\":\\\"Youth license 2026\\\",\\\"tier\\\":\\\"Youth license\\\",\\\"amount\\\":3000,\\\"id\\\":10003},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"autumn-tournament-2026\\\",\\\"title\\\":\\\"Autumn tournament 2026\\\",\\\"tier\\\":\\\"Tournament ticket\\\",\\\"amount\\\":1500,\\\"id\\\":10004},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"annual-gala-2026\\\",\\\"title\\\":\\\"Annual gala 2026\\\",\\\"tier\\\":\\\"Gala ticket\\\",\\\"amount\\\":3500,\\\"id\\\":10005},{\\\"type\\\":\\\"Event\\\",\\\"slug\\\":\\\"discovery-workshop-2026\\\",\\\"title\\\":\\\"Discovery workshop 2026\\\",\\\"tier\\\":\\\"Workshop registration\\\",\\\"amount\\\":2000,\\\"id\\\":10006},{\\\"type\\\":\\\"Donation\\\",\\\"slug\\\":\\\"free-donations-2026\\\",\\\"title\\\":\\\"Free donations 2026\\\",\\\"tier\\\":\\\"Donation\\\",\\\"amount\\\":2500,\\\"id\\\":10007},{\\\"type\\\":\\\"Donation\\\",\\\"slug\\\":\\\"equipment-support-2026\\\",\\\"title\\\":\\\"Equipment support 2026\\\",\\\"tier\\\":\\\"Equipment donation\\\",\\\"amount\\\":4000,\\\"id\\\":10008},{\\\"type\\\":\\\"CrowdFunding\\\",\\\"slug\\\":\\\"community-minibus-2026\\\",\\\"title\\\":\\\"Community minibus project\\\",\\\"tier\\\":\\\"Project contribution\\\",\\\"amount\\\":5000,\\\"id\\\":10009},{\\\"type\\\":\\\"CrowdFunding\\\",\\\"slug\\\":\\\"training-room-2026\\\",\\\"title\\\":\\\"New training room project\\\",\\\"tier\\\":\\\"Project contribution\\\",\\\"amount\\\":7500,\\\"id\\\":10010},{\\\"type\\\":\\\"Shop\\\",\\\"slug\\\":\\\"club-shop-2026\\\",\\\"title\\\":\\\"Club shop 2026\\\",\\\"tier\\\":\\\"Club T-shirt\\\",\\\"amount\\\":2000,\\\"id\\\":10011},{\\\"type\\\":\\\"Shop\\\",\\\"slug\\\":\\\"equipment-shop-2026\\\",\\\"title\\\":\\\"Equipment shop 2026\\\",\\\"tier\\\":\\\"Equipment pack\\\",\\\"amount\\\":6000,\\\"id\\\":10012},{\\\"type\\\":\\\"PaymentForm\\\",\\\"slug\\\":\\\"workshop-balance-2026\\\",\\\"title\\\":\\\"Workshop balance 2026\\\",\\\"tier\\\":\\\"Workshop balance\\\",\\\"amount\\\":8000,\\\"id\\\":10013},{\\\"type\\\":\\\"PaymentForm\\\",\\\"slug\\\":\\\"trip-contribution-2026\\\",\\\"title\\\":\\\"Trip contribution 2026\\\",\\\"tier\\\":\\\"Trip contribution\\\",\\\"amount\\\":5500,\\\"id\\\":10014},{\\\"type\\\":\\\"Checkout\\\",\\\"slug\\\":\\\"membership-supplement-2026\\\",\\\"title\\\":\\\"Membership supplement\\\",\\\"tier\\\":\\\"Membership supplement\\\",\\\"amount\\\":1200,\\\"id\\\":10015},{\\\"type\\\":\\\"Checkout\\\",\\\"slug\\\":\\\"exceptional-contribution-2026\\\",\\\"title\\\":\\\"Exceptional contribution\\\",\\\"tier\\\":\\\"Exceptional contribution\\\",\\\"amount\\\":2500,\\\"id\\\":10016}]';\\n    $forms = json_decode($catalog_json, true);\\n    return is_array($forms) ? $forms : array();\\n}\\n\\nfunction scha_pg_public_form_url($slug) {\\n    return home_url('\\\/helloasso-demo-placeholder\\\/?form=' . rawurlencode((string) $slug));\\n}\\n\\nfunction scha_pg_raw_forms() {\\n    $rows = array();\\n    foreach (scha_pg_catalog() as $i => $form) {\\n        $url = scha_pg_public_form_url($form['slug']);\\n        $rows[] = array(\\n            'id' => (int) $form['id'],\\n            'formType' => $form['type'],\\n            'formSlug' => $form['slug'],\\n            'title' => $form['title'],\\n            'state' => 'Public',\\n            'url' => $url,\\n            'widgetFullUrl' => $url,\\n            'widgetButtonUrl' => $url,\\n            'creationDate' => '2026-01-' . str_pad((string) (($i % 9) + 10), 2, '0', STR_PAD_LEFT) . 'T09:00:00+01:00',\\n            'lastUpdate' => '2026-09-' . str_pad((string) (($i % 5) + 1), 2, '0', STR_PAD_LEFT) . 'T10:30:00+02:00',\\n        );\\n    }\\n    return $rows;\\n}\\n\\nfunction scha_pg_person($index, $role = 'participant') {\\n    $index = max(1, (int) $index);\\n    $prefix = $role === 'payer' ? scha_pg_text('Payer', 'Payeur') : 'Participant';\\n    return array(\\n        'firstName' => scha_pg_text('Demo', 'D\\u00e9mo'),\\n        'lastName' => $prefix . ' ' . str_pad((string) $index, 2, '0', STR_PAD_LEFT),\\n        'email' => strtolower($prefix) . str_pad((string) $index, 2, '0', STR_PAD_LEFT) . '@example.org',\\n        'dateOfBirth' => $role === 'payer' ? '1985-05-15' : '1995-0' . (($index % 8) + 1) . '-12',\\n        'address' => (10 + $index) . scha_pg_text(' Example Street', ' rue de l\\u2019Exemple'),\\n        'zipCode' => '31000',\\n        'city' => 'Toulouse',\\n        'country' => 'France',\\n    );\\n}\\n\\nfunction scha_pg_custom_fields($form, $index) {\\n    $fields = array(\\n        array('name' => scha_pg_text('Demo consent', 'Consentement de d\\u00e9monstration'), 'answer' => ($index % 2) ? scha_pg_text('Yes', 'Oui') : scha_pg_text('No', 'Non')),\\n        array('name' => scha_pg_text('Reference', 'R\\u00e9f\\u00e9rence'), 'answer' => 'DEMO-' . strtoupper(substr(md5($form['slug'] . '|' . $index), 0, 8))),\\n    );\\n    if ($form['type'] === 'Membership') {\\n        $fields[] = array('name' => scha_pg_text('Emergency contact', 'Contact d\\u2019urgence'), 'answer' => scha_pg_text('Demo contact ', 'Contact de d\\u00e9monstration ') . $index);\\n    } elseif ($form['type'] === 'Event') {\\n        $fields[] = array('name' => scha_pg_text('Dietary information', 'Informations alimentaires'), 'answer' => ($index % 2) ? scha_pg_text('None', 'Aucune') : scha_pg_text('Vegetarian', 'V\\u00e9g\\u00e9tarien'));\\n    } elseif ($form['type'] === 'Shop') {\\n        $fields[] = array('name' => scha_pg_text('Size', 'Taille'), 'answer' => array('S','M','L','XL')[$index % 4]);\\n    } elseif ($form['type'] === 'Donation' || $form['type'] === 'CrowdFunding') {\\n        $fields[] = array('name' => scha_pg_text('Display donor name', 'Afficher le nom du donateur'), 'answer' => ($index % 2) ? scha_pg_text('Yes', 'Oui') : scha_pg_text('No', 'Non'));\\n    } else {\\n        $fields[] = array('name' => scha_pg_text('Comment', 'Commentaire'), 'answer' => scha_pg_text('Synthetic Playground example', 'Exemple fictif Playground'));\\n    }\\n    return $fields;\\n}\\n\\nfunction scha_pg_orders_for_form($form) {\\n    $orders = array();\\n    $form_index = 0;\\n    foreach (scha_pg_catalog() as $idx => $candidate) {\\n        if ($candidate['slug'] === $form['slug'] && $candidate['type'] === $form['type']) { $form_index = $idx; break; }\\n    }\\n    for ($j = 1; $j <= 3; $j++) {\\n        $n = ($form_index * 3) + $j;\\n        $order_id = 200000 + ($form_index * 10) + $j;\\n        $item_id = 300000 + ($form_index * 10) + $j;\\n        $base_amount = (int) $form['amount'];\\n        if ($form['type'] === 'Donation') $base_amount = array(2500,5000,10000)[$j-1];\\n        if ($form['type'] === 'CrowdFunding') $base_amount += ($j-1) * 2500;\\n        $payer = scha_pg_person($n, 'payer');\\n        $participant = scha_pg_person($n, 'participant');\\n\\n        $payment_count = ($j === 2 && in_array($form['type'], array('Membership','CrowdFunding','PaymentForm','Checkout'), true)) ? 2 : 1;\\n        $payments = array();\\n        $remaining = $base_amount;\\n        for ($p = 1; $p <= $payment_count; $p++) {\\n            $pay_amount = ($payment_count === 2 && $p === 1) ? (int) floor($base_amount \\\/ 2) : $remaining;\\n            $remaining -= $pay_amount;\\n            $state = ($j === 3 && ($form_index % 4 === 0)) ? 'Refunded' : 'Authorized';\\n            $payments[] = array(\\n                'id' => 400000 + ($form_index * 100) + ($j * 10) + $p,\\n                'orderId' => $order_id,\\n                'itemId' => $item_id,\\n                'formId' => (int) $form['id'],\\n                'formType' => $form['type'],\\n                'formSlug' => $form['slug'],\\n                'state' => $state,\\n                'cashOutState' => $state === 'Refunded' ? 'Refunded' : 'Transferred',\\n                'amount' => $pay_amount,\\n                'date' => '2026-08-' . str_pad((string) (5 + (($form_index + $j + $p) % 20)), 2, '0', STR_PAD_LEFT) . 'T14:15:00+02:00',\\n                'installmentNumber' => $payment_count === 2 ? $p : 1,\\n                'paymentMeans' => ($j % 2) ? 'Card' : 'BankCard',\\n                'payer' => $payer,\\n            );\\n        }\\n\\n        $item_state = ($j === 3 && ($form_index % 4 === 0)) ? 'Canceled' : 'Processed';\\n        $item = array(\\n            'id' => $item_id,\\n            'orderId' => $order_id,\\n            'formId' => (int) $form['id'],\\n            'formType' => $form['type'],\\n            'formSlug' => $form['slug'],\\n            'name' => $form['tier'],\\n            'tierType' => $form['type'] === 'Membership' ? 'Membership' : ($form['type'] === 'Event' ? 'Registration' : 'Payment'),\\n            'state' => $item_state,\\n            'amount' => $base_amount,\\n            'user' => $participant,\\n            'payer' => $payer,\\n            'customFields' => scha_pg_custom_fields($form, $n),\\n            'payments' => $payments,\\n        );\\n\\n        $orders[] = array(\\n            'id' => $order_id,\\n            'formId' => (int) $form['id'],\\n            'formType' => $form['type'],\\n            'formSlug' => $form['slug'],\\n            'date' => '2026-08-' . str_pad((string) (4 + (($form_index + $j) % 20)), 2, '0', STR_PAD_LEFT) . 'T13:30:00+02:00',\\n            'lastUpdate' => '2026-09-0' . (($j % 3) + 1) . 'T10:00:00+02:00',\\n            'amount' => $base_amount,\\n            'payer' => $payer,\\n            'items' => array($item),\\n            'payments' => $payments,\\n        );\\n    }\\n    return $orders;\\n}\\n\\nfunction scha_pg_find_form($type, $slug) {\\n    foreach (scha_pg_catalog() as $form) {\\n        if (strcasecmp((string) $form['type'], (string) $type) === 0 && (string) $form['slug'] === (string) $slug) return $form;\\n    }\\n    return null;\\n}\\n\\nfunction scha_pg_flat_items($form) {\\n    $rows = array();\\n    foreach (scha_pg_orders_for_form($form) as $order) {\\n        foreach ($order['items'] as $item) $rows[] = $item;\\n    }\\n    return $rows;\\n}\\n\\nfunction scha_pg_flat_payments($form) {\\n    $rows = array();\\n    foreach (scha_pg_orders_for_form($form) as $order) {\\n        foreach ($order['payments'] as $payment) $rows[] = $payment;\\n    }\\n    return $rows;\\n}\\n\\nfunction scha_pg_http_response($payload, $code = 200) {\\n    return array(\\n        'headers' => array('content-type' => 'application\\\/json; charset=utf-8'),\\n        'body' => wp_json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),\\n        'response' => array('code' => (int) $code, 'message' => $code === 200 ? 'OK' : 'Error'),\\n        'cookies' => array(),\\n        'filename' => null,\\n    );\\n}\\n\\nfunction scha_pg_mock_helloasso($preempt, $args, $url) {\\n    $host = strtolower((string) wp_parse_url($url, PHP_URL_HOST));\\n    if (!in_array($host, array('api.helloasso.com','api.helloasso-sandbox.com'), true)) return $preempt;\\n\\n    $path = (string) wp_parse_url($url, PHP_URL_PATH);\\n    if ($path === '\\\/oauth2\\\/token') {\\n        return scha_pg_http_response(array('access_token' => 'playground-demo-token', 'token_type' => 'Bearer', 'expires_in' => 3600));\\n    }\\n\\n    if (!preg_match('#^\\\/v5\\\/organizations\\\/([^\\\/]+)(.*)$#', $path, $m)) {\\n        return scha_pg_http_response(array('error' => 'Not found'), 404);\\n    }\\n    $org = rawurldecode($m[1]);\\n    $tail = $m[2];\\n    if ($org !== 'association-demo-sprint') return scha_pg_http_response(array('error' => 'Demo organization not found'), 404);\\n\\n    if ($tail === '' || $tail === '\\\/') {\\n        return scha_pg_http_response(array('organizationSlug' => $org, 'name' => scha_pg_text('Sprint Demo Association', 'Association D\\u00e9mo Sprint'), 'type' => 'Association'));\\n    }\\n    if ($tail === '\\\/orders') {\\n        $all = array();\\n        foreach (scha_pg_catalog() as $form) $all = array_merge($all, scha_pg_orders_for_form($form));\\n        return scha_pg_http_response(array('data' => array_slice($all, 0, 1), 'pagination' => array('totalCount' => count($all), 'continuationToken' => null)));\\n    }\\n    if ($tail === '\\\/forms') {\\n        $data = scha_pg_raw_forms();\\n        return scha_pg_http_response(array('data' => $data, 'pagination' => array('totalCount' => count($data), 'continuationToken' => null)));\\n    }\\n    if (preg_match('#^\\\/forms\\\/([^\\\/]+)\\\/([^\\\/]+)\\\/(items|orders|payments)$#', $tail, $fm)) {\\n        $type = rawurldecode($fm[1]);\\n        $slug = rawurldecode($fm[2]);\\n        $kind = $fm[3];\\n        $form = scha_pg_find_form($type, $slug);\\n        if (!$form) return scha_pg_http_response(array('error' => 'Demo form not found'), 404);\\n        if ($kind === 'items') $data = scha_pg_flat_items($form);\\n        elseif ($kind === 'payments') $data = scha_pg_flat_payments($form);\\n        else $data = scha_pg_orders_for_form($form);\\n        return scha_pg_http_response(array('data' => $data, 'pagination' => array('totalCount' => count($data), 'continuationToken' => null)));\\n    }\\n    return scha_pg_http_response(array('error' => 'Unsupported demo endpoint'), 404);\\n}\\nadd_filter('pre_http_request', 'scha_pg_mock_helloasso', 10, 3);\\n\\nfunction scha_pg_create_demo_pages() {\\n    $placeholder = get_page_by_path('helloasso-demo-placeholder');\\n    if (!$placeholder) {\\n        wp_insert_post(array(\\n            'post_type' => 'page', 'post_status' => 'publish',\\n            'post_title' => scha_pg_text('HelloAsso form placeholder', 'Page fictive du formulaire HelloAsso'), 'post_name' => 'helloasso-demo-placeholder',\\n            'post_content' => scha_pg_text('<!-- wp:heading --><h2 class=\\\"wp-block-heading\\\">HelloAsso Playground placeholder<\\\/h2><!-- \\\/wp:heading --><!-- wp:paragraph --><p>This local page stands in for the external HelloAsso hosted form during the WordPress.org Playground preview. The plugin data and synchronization screens use synthetic responses only.<\\\/p><!-- \\\/wp:paragraph -->', '<!-- wp:heading --><h2 class=\\\"wp-block-heading\\\">Page fictive HelloAsso pour Playground<\\\/h2><!-- \\\/wp:heading --><!-- wp:paragraph --><p>Cette page locale remplace le formulaire externe h\\u00e9berg\\u00e9 par HelloAsso pendant l\\u2019aper\\u00e7u WordPress.org Playground. Les donn\\u00e9es du plugin et les \\u00e9crans de synchronisation utilisent uniquement des r\\u00e9ponses fictives.<\\\/p><!-- \\\/wp:paragraph -->'),\\n        ));\\n    }\\n\\n    $showcase = get_page_by_path('sprint-connect-helloasso-demo');\\n    if (!$showcase) {\\n        $content = scha_pg_text('<!-- wp:heading --><h2 class=\\\"wp-block-heading\\\">Sprint Connect for HelloAsso \\u2014 Playground demo<\\\/h2><!-- \\\/wp:heading -->', '<!-- wp:heading --><h2 class=\\\"wp-block-heading\\\">Sprint Connect for HelloAsso \\u2014 D\\u00e9mo Playground<\\\/h2><!-- \\\/wp:heading -->');\\n        $content .= scha_pg_text('<!-- wp:paragraph --><p>All content below is synthetic. Standard HelloAsso forms use local placeholder links in this preview; Checkout examples render local transaction data.<\\\/p><!-- \\\/wp:paragraph -->', '<!-- wp:paragraph --><p>Tout le contenu ci-dessous est fictif. Dans cet aper\\u00e7u, les formulaires HelloAsso standards utilisent des liens locaux de d\\u00e9monstration ; les exemples Checkout affichent des donn\\u00e9es de transaction locales.<\\\/p><!-- \\\/wp:paragraph -->');\\n        $representatives = array(\\n            array('Membership','adult-membership-2026',scha_pg_text('Membership', 'Adh\\u00e9sion')),\\n            array('Event','annual-gala-2026',scha_pg_text('Event \\\/ ticketing', '\\u00c9v\\u00e9nement \\\/ billetterie')),\\n            array('Donation','free-donations-2026',scha_pg_text('Donation', 'Don')),\\n            array('CrowdFunding','community-minibus-2026',scha_pg_text('Crowdfunding', 'Financement participatif')),\\n            array('Shop','club-shop-2026',scha_pg_text('Shop', 'Boutique')),\\n            array('PaymentForm','workshop-balance-2026',scha_pg_text('Payment form', 'Formulaire de paiement')),\\n            array('Checkout','membership-supplement-2026','Checkout'),\\n        );\\n        foreach ($representatives as $r) {\\n            $content .= '<!-- wp:heading {\\\"level\\\":3} --><h3 class=\\\"wp-block-heading\\\">' . esc_html($r[2]) . '<\\\/h3><!-- \\\/wp:heading -->';\\n            if ($r[0] === 'Checkout') {\\n                $content .= '[sprint_helloasso form=\\\"' . esc_attr($r[1]) . '\\\" type=\\\"Checkout\\\" view=\\\"both\\\" limit=\\\"10\\\" visibility=\\\"public\\\" details=\\\"1\\\"]';\\n            } else {\\n                $label = scha_pg_is_fr() ? 'Ouvrir l\\u2019exemple fictif : ' . $r[2] : 'Open synthetic ' . $r[2] . ' example';\\n                $content .= '[sprint_helloasso form=\\\"' . esc_attr($r[1]) . '\\\" type=\\\"' . esc_attr($r[0]) . '\\\" mode=\\\"button\\\" label=\\\"' . esc_attr($label) . '\\\"]';\\n            }\\n        }\\n        wp_insert_post(array(\\n            'post_type' => 'page', 'post_status' => 'publish',\\n            'post_title' => scha_pg_text('Sprint Connect for HelloAsso Demo', 'Sprint Connect for HelloAsso \\u2014 D\\u00e9mo'), 'post_name' => 'sprint-connect-helloasso-demo',\\n            'post_content' => $content,\\n        ));\\n    }\\n}\\n\\nfunction scha_pg_seed_demo() {\\n    if (get_option('scha_playground_demo_seeded') === '1') return;\\n\\n    update_option('blogname', scha_pg_text('Sprint Connect for HelloAsso \\u2014 Playground Demo', 'Sprint Connect for HelloAsso \\u2014 D\\u00e9mo Playground'), false);\\n    update_option('blogdescription', scha_pg_text('Synthetic HelloAsso data for WordPress.org preview', 'Donn\\u00e9es HelloAsso fictives pour l\\u2019aper\\u00e7u WordPress.org'), false);\\n    if (!class_exists('SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\Database\\\\\\\\Schema') || !class_exists('SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\Database\\\\\\\\Repository') || !class_exists('SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\HelloAsso\\\\\\\\Normalizer')) return;\\n\\n    $schema = 'SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\Database\\\\\\\\Schema';\\n    $repo = 'SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\Database\\\\\\\\Repository';\\n    $normalizer = 'SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\HelloAsso\\\\\\\\Normalizer';\\n    $page_manager = 'SprintPlugins\\\\\\\\ConnectHelloAsso\\\\\\\\Integration\\\\\\\\PageManager';\\n\\n    $schema::install();\\n    $org = 'association-demo-sprint';\\n    $first = scha_pg_catalog()[0];\\n    $settings = array(\\n        'environment' => 'sandbox',\\n        'helloasso_connections' => array(\\n            'production' => array('client_id'=>'','client_secret'=>'','association_slug'=>'','form_id'=>0,'form_slug'=>'','form_type'=>'Membership'),\\n            'sandbox' => array(\\n                'client_id' => 'playground-demo-client-id',\\n                'client_secret' => 'playground-demo-client-secret',\\n                'association_slug' => $org,\\n                'form_id' => (int) $first['id'],\\n                'form_slug' => $first['slug'],\\n                'form_type' => $first['type'],\\n            ),\\n        ),\\n        'client_id' => 'playground-demo-client-id',\\n        'client_secret' => 'playground-demo-client-secret',\\n        'association_slug' => $org,\\n        'form_id' => (int) $first['id'],\\n        'form_slug' => $first['slug'],\\n        'form_type' => $first['type'],\\n        'duplicate_strategy' => 'email',\\n        'send_welcome_email' => 0,\\n        'field_mapping' => array(),\\n        'available_helloasso_fields' => array(),\\n        'manual_helloasso_fields' => array(),\\n        'cron_enabled' => 0,\\n        'cron_interval_seconds' => 900,\\n        'sync_mode' => 'all',\\n        'csv_separator' => 'semicolon',\\n        'csv_bom' => 1,\\n        'log_retention_days' => 90,\\n        'delete_data_on_uninstall' => 0,\\n    );\\n    update_option('scha_settings', $settings, false);\\n    update_option('scha_display_mode_default', 'complete', false);\\n\\n    $raw_forms = scha_pg_raw_forms();\\n    $normalized_forms = array();\\n    foreach ($raw_forms as $raw_form) $normalized_forms[] = $normalizer::form($raw_form);\\n    $repo::reconcile_forms_payload(array(\\n        'data' => $normalized_forms,\\n        'raw_data' => $raw_forms,\\n        'pagination' => array('loadedCount'=>count($normalized_forms),'totalCount'=>count($normalized_forms)),\\n    ), $org);\\n\\n    foreach (scha_pg_catalog() as $form) {\\n        $raw_orders = scha_pg_orders_for_form($form);\\n        $normalized_orders = array();\\n        foreach ($raw_orders as $raw_order) {\\n            $normalized_orders[] = $normalizer::order($raw_order, array('form_id'=>(int)$form['id'],'form_type'=>$form['type'],'form_slug'=>$form['slug']));\\n        }\\n        $repo::persist_orders_payload(array('data'=>$normalized_orders,'raw_data'=>$raw_orders), $org);\\n        $repo::upsert_sync_state(array(\\n            'form_id' => (int) $form['id'], 'helloasso_form_id' => (int) $form['id'],\\n            'form_type' => $form['type'], 'form_slug' => $form['slug'], 'form_title' => $form['title'],\\n            'enabled' => 0, 'sync_mode' => 'new', 'cursor_timestamp' => strtotime('2026-09-01 10:00:00'),\\n            'last_attempt_at' => '2026-09-01 10:00:00', 'last_success_at' => '2026-09-01 10:00:02',\\n            'last_status' => 'success', 'last_message' => scha_pg_text('Synthetic Playground synchronization', 'Synchronisation fictive Playground'),\\n            'last_created' => 3, 'last_updated' => 0, 'last_skipped' => 0, 'last_error_count' => 0,\\n        ), $org, false);\\n    }\\n\\n    \\\/\\\/ Create a few already-linked WordPress accounts while leaving many rows unlinked for import testing.\\n    $linked = 0;\\n    foreach (scha_pg_catalog() as $form) {\\n        if ($linked >= 10) break;\\n        $order = scha_pg_orders_for_form($form)[0];\\n        $item = $order['items'][0];\\n        $person = $item['user'];\\n        $email = sanitize_email($person['email']);\\n        $user = get_user_by('email', $email);\\n        if (!$user) {\\n            $username = sanitize_user('demo-' . $form['type'] . '-' . ($linked + 1), true);\\n            if (username_exists($username)) $username .= '-' . ($linked + 10);\\n            $uid = wp_insert_user(array(\\n                'user_login' => $username, 'user_pass' => wp_generate_password(20, true, true),\\n                'user_email' => $email, 'first_name' => $person['firstName'], 'last_name' => $person['lastName'],\\n                'display_name' => $person['firstName'] . ' ' . $person['lastName'], 'role' => 'subscriber',\\n            ));\\n            if (is_wp_error($uid)) continue;\\n        } else {\\n            $uid = $user->ID;\\n        }\\n        update_user_meta($uid, 'scha_connected_user', 1);\\n        update_user_meta($uid, 'scha_member', 1);\\n        update_user_meta($uid, 'scha_form_id', (int) $form['id']);\\n        update_user_meta($uid, 'scha_form_type', $form['type']);\\n        update_user_meta($uid, 'scha_form_slug', $form['slug']);\\n        update_user_meta($uid, 'scha_order_id', (int) $order['id']);\\n        update_user_meta($uid, 'scha_item_id', (int) $item['id']);\\n        add_user_meta($uid, 'scha_item_ids', (int) $item['id'], false);\\n        update_user_meta($uid, 'scha_payment_ids', array_map('intval', wp_list_pluck($item['payments'], 'id')));\\n        update_user_meta($uid, 'scha_payment_states', array_values(array_unique(wp_list_pluck($item['payments'], 'state'))));\\n        update_user_meta($uid, 'scha_person_role', 'participant');\\n        update_user_meta($uid, 'scha_raw_data', wp_json_encode($item, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));\\n        $repo::link_user_to_item((int) $item['id'], $org, (int) $uid);\\n        $linked++;\\n    }\\n\\n    $logs = array(\\n        (scha_pg_is_fr() ? array('time'=>'2026-09-01 10:00:02','status'=>'success','message'=>'Import de d\\u00e9monstration Playground termin\\u00e9','created'=>10,'updated'=>0,'skipped'=>2,'errors'=>array(),'details'=>array(),'duration'=>1.482,'total_fetched'=>12,'total_processed'=>12,'sync_mode'=>'all','manual'=>1,'form_title'=>'Adult membership 2026','form_type'=>'Membership','form_slug'=>'adult-membership-2026') : array('time'=>'2026-09-01 10:00:02','status'=>'success','message'=>'Playground demo import completed','created'=>10,'updated'=>0,'skipped'=>2,'errors'=>array(),'details'=>array(),'duration'=>1.482,'total_fetched'=>12,'total_processed'=>12,'sync_mode'=>'all','manual'=>1,'form_title'=>'Adult membership 2026','form_type'=>'Membership','form_slug'=>'adult-membership-2026')),\\n        (scha_pg_is_fr() ? array('time'=>'2026-08-25 09:15:01','status'=>'success','message'=>'Synchronisation incr\\u00e9mentale fictive','created'=>3,'updated'=>2,'skipped'=>1,'errors'=>array(),'details'=>array(),'duration'=>0.842,'total_fetched'=>6,'total_processed'=>6,'sync_mode'=>'new','manual'=>0,'form_title'=>'Annual gala 2026','form_type'=>'Event','form_slug'=>'annual-gala-2026') : array('time'=>'2026-08-25 09:15:01','status'=>'success','message'=>'Synthetic incremental synchronization','created'=>3,'updated'=>2,'skipped'=>1,'errors'=>array(),'details'=>array(),'duration'=>0.842,'total_fetched'=>6,'total_processed'=>6,'sync_mode'=>'new','manual'=>0,'form_title'=>'Annual gala 2026','form_type'=>'Event','form_slug'=>'annual-gala-2026')),\\n    );\\n    update_option('scha_cron_logs', $logs, false);\\n    update_option('scha_last_success_timestamp', strtotime('2026-09-01 10:00:02'), false);\\n    update_option('scha_last_success_time', '2026-09-01 10:00:02', false);\\n    update_option('scha_helloasso_http_health', array('status'=>'ok','type'=>'','message'=>'','http_code'=>200,'consecutive_failures'=>0,'cooldown_until'=>0,'last_error_at'=>'','last_success_at'=>'2026-09-01 10:00:02','retry_after'=>0), false);\\n\\n    scha_pg_create_demo_pages();\\n    if (class_exists($page_manager)) {\\n        $page_manager::sync_catalog_pages($org);\\n        $checkout_pages = get_posts(array('post_type'=>'page','post_status'=>'draft','posts_per_page'=>-1,'meta_key'=>'_scha_managed_form_type','meta_value'=>'Checkout'));\\n        foreach ($checkout_pages as $page) wp_update_post(array('ID'=>$page->ID,'post_status'=>'publish'));\\n    }\\n\\n    update_option('scha_playground_demo_seeded', '1', false);\\n}\\nadd_action('init', 'scha_pg_seed_demo', 50);\\n\\nfunction scha_pg_demo_notice() {\\n    if (!current_user_can('manage_options')) return;\\n    $screen = function_exists('get_current_screen') ? get_current_screen() : null;\\n    if (!$screen || strpos((string) $screen->id, 'sprint-connect-for-helloasso') === false) return;\\n    $front = get_page_by_path('sprint-connect-helloasso-demo');\\n    $link = $front ? get_permalink($front) : home_url('\\\/');\\n    if (scha_pg_is_fr()) {\\n    echo '<div class=\\\"notice notice-info\\\"><p><strong>D\\u00e9mo WordPress.org Playground :<\\\/strong> tous les formulaires, personnes, commandes et paiements HelloAsso sont fictifs. Les appels API sont intercept\\u00e9s localement ; aucun compte HelloAsso r\\u00e9el ni aucune donn\\u00e9e personnelle r\\u00e9elle ne sont utilis\\u00e9s. <a href=\\\"' . esc_url($link) . '\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">Ouvrir la d\\u00e9mo c\\u00f4t\\u00e9 site<\\\/a>.<\\\/p><\\\/div>';\\n    } else {\\n    echo '<div class=\\\"notice notice-info\\\"><p><strong>WordPress.org Playground demo:<\\\/strong> all HelloAsso forms, people, orders and payments are synthetic. API calls are intercepted locally; no real HelloAsso account or personal data is used. <a href=\\\"' . esc_url($link) . '\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">Open the front-end demo<\\\/a>.<\\\/p><\\\/div>';\\n    }\\n}\\nadd_action('admin_notices', 'scha_pg_demo_notice');\\n\"},{\"step\":\"runPHP\",\"code\":\"<?php require '\\\/wordpress\\\/wp-load.php'; scha_pg_seed_demo();\"},{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"}]}"}},"all_blocks":{"sprint-connect\/helloasso-form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"sprint-connect\/helloasso-form","version":"1.0.0","title":"HelloAsso: form or Checkout","category":"widgets","icon":"tickets-alt","description":"Displays a public HelloAsso form or local data from a Checkout form.","textdomain":"sprint-connect-for-helloasso","attributes":{"form":{"type":"string","default":""},"type":{"type":"string","default":""},"mode":{"type":"string","default":"iframe"},"height":{"type":"number","default":900},"label":{"type":"string","default":"Open the HelloAsso form"},"view":{"type":"string","default":"both"},"limit":{"type":"number","default":10},"visibility":{"type":"string","default":"public"},"title":{"type":"string","default":""},"details":{"type":"boolean","default":false}},"supports":{"html":false,"align":["wide","full"]},"editorScript":"scha-helloasso-block-editor","editorStyle":"file:.\/editor.css"}},"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1-fr.png":{"filename":"screenshot-1-fr.png","revision":3683842,"resolution":"1","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-1.png":{"filename":"screenshot-1.png","revision":3683842,"resolution":"1","location":"assets","locale":"","width":1440,"height":900},"screenshot-2-fr.png":{"filename":"screenshot-2-fr.png","revision":3683842,"resolution":"2","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3683842,"resolution":"2","location":"assets","locale":"","width":1440,"height":900},"screenshot-3-fr.png":{"filename":"screenshot-3-fr.png","revision":3683842,"resolution":"3","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3683842,"resolution":"3","location":"assets","locale":"","width":1440,"height":900},"screenshot-4-fr.png":{"filename":"screenshot-4-fr.png","revision":3683842,"resolution":"4","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3683842,"resolution":"4","location":"assets","locale":"","width":1440,"height":900},"screenshot-5-fr.png":{"filename":"screenshot-5-fr.png","revision":3683842,"resolution":"5","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3683842,"resolution":"5","location":"assets","locale":"","width":1440,"height":900}},"screenshots":{"1":"HelloAsso OAuth connection status, selected organization, and synchronization information.","2":"Available HelloAsso membership, ticketing, donation, and campaign forms.","3":"Orders, participants, payments, and installment status imported from HelloAsso.","4":"WordPress account matching and creation workflow.","5":"Gutenberg block, shortcode, sandbox, and Sprint Club display settings."}},"plugin_section":[],"plugin_tags":[8874,177739,1932,1887,1917],"plugin_category":[45,58],"plugin_contributors":[274079],"plugin_business_model":[],"class_list":["post-363631","plugin","type-plugin","status-publish","hentry","plugin_tags-association","plugin_tags-helloasso","plugin_tags-membership","plugin_tags-payments","plugin_tags-users","plugin_category-ecommerce","plugin_category-user-management","plugin_contributors-sprintplugins","plugin_committers-sprintplugins"],"banners":{"banner":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/banner-772x250.png?rev=3683842","banner_2x":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/banner-1544x500.png?rev=3683842","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/icon.svg?rev=3683842","icon":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/icon.svg?rev=3683842","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/screenshot-1.png?rev=3683842","caption":"HelloAsso OAuth connection status, selected organization, and synchronization information."},{"src":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/screenshot-2.png?rev=3683842","caption":"Available HelloAsso membership, ticketing, donation, and campaign forms."},{"src":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/screenshot-3.png?rev=3683842","caption":"Orders, participants, payments, and installment status imported from HelloAsso."},{"src":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/screenshot-4.png?rev=3683842","caption":"WordPress account matching and creation workflow."},{"src":"https:\/\/ps.w.org\/sprint-connect-for-helloasso\/assets\/screenshot-5.png?rev=3683842","caption":"Gutenberg block, shortcode, sandbox, and Sprint Club display settings."}],"raw_content":"<!--section=description-->\n<p>Sprint Connect for HelloAsso helps clubs and associations connect one HelloAsso organization to WordPress.<\/p>\n\n<p>The free plugin provides:<\/p>\n\n<ul>\n<li>OAuth connection to HelloAsso.<\/li>\n<li>Production and sandbox environments.<\/li>\n<li>Manual retrieval and selection of HelloAsso forms.<\/li>\n<li>Local review of orders, items, participants, payers, payments, and installment status.<\/li>\n<li>CSV export of the filtered backend data explorer.<\/li>\n<li>Manual full or incremental imports and WordPress user matching or creation.<\/li>\n<li>A Gutenberg block and shortcode for displaying selected HelloAsso forms.<\/li>\n<li>Essential, Complete, and Expert administration modes.<\/li>\n<li>Optional display-mode inheritance and workspace integration with Sprint Club.<\/li>\n<li>Privacy exporters and erasers for imported personal data.<\/li>\n<li>A public API and neutral extension bridge for compatible add-ons.<\/li>\n<\/ul>\n\n<p>An optional, separately distributed Pro add-on can provide advanced field mapping, custom emails, automations, webhooks, snippets, backups, and additional synchronization tools. Premium implementation code, the license SDK, and the private updater are not included in this WordPress.org package.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to HelloAsso only after a site administrator configures API credentials and starts a connection, synchronization, or import.<\/p>\n\n<p>Depending on the requested action, the plugin sends the configured client identifier and secret for OAuth authentication, the organization identifier, access or refresh tokens, and API request parameters. It receives organization, form, order, payer, participant, payment, and related campaign data made available to the configured HelloAsso API client.<\/p>\n\n<p>Production requests use <code>https:\/\/api.helloasso.com<\/code>. Sandbox requests use <code>https:\/\/api.helloasso-sandbox.com<\/code> when sandbox mode is enabled. Embedded or linked forms may direct visitors to <code>https:\/\/www.helloasso.com<\/code> or the HelloAsso sandbox website.<\/p>\n\n<p>The use of HelloAsso is subject to its terms and privacy policy:<\/p>\n\n<ul>\n<li>Association terms: https:\/\/info.helloasso.com\/cgu-associations<\/li>\n<li>User terms: https:\/\/info.helloasso.com\/cgu-utilisateurs<\/li>\n<li>Privacy policy: https:\/\/info.helloasso.com\/politique-de-confidentialite<\/li>\n<li>API documentation: https:\/\/dev.helloasso.com\/docs\/api-overview<\/li>\n<\/ul>\n\n<p>Sprint Plugins is not affiliated with or endorsed by HelloAsso. HelloAsso is a trademark of its respective owner.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>The plugin can store API credentials, OAuth tokens, organization settings, imported identifiers, form metadata, order information, participant information, payer information, payment status, and WordPress user-matching decisions.<\/p>\n\n<p>These records may contain personal data received from HelloAsso. The site administrator is responsible for having a lawful basis for importing and using this data, limiting access, defining retention periods, and providing appropriate privacy information to members and contributors.<\/p>\n\n<p>No data is sent to Sprint Plugins by the free plugin.<\/p>\n\n<h3>Source code<\/h3>\n\n<p>The JavaScript distributed by this plugin is human-readable and is not minified. No private build toolchain is required.<\/p>\n\n<p>The JavaScript authoring sources are included in <code>src\/js\/app.js<\/code> and <code>src\/blocks\/helloasso-form\/editor.js<\/code>; their runtime copies are <code>assets\/js\/app.js<\/code> and <code>assets\/blocks\/helloasso-form\/editor.js<\/code>. To regenerate the runtime assets, copy the source files unchanged. Build details are also documented in <code>src\/README.txt<\/code>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate Sprint Connect for HelloAsso.<\/li>\n<li>Open Sprint Connect for HelloAsso &gt; Settings.<\/li>\n<li>Configure the Production and\/or Sandbox connection profile. Each environment keeps its own API credentials and organization slug.<\/li>\n<li>Save the environment you want to use, open Forms, then retrieve and select the available forms manually.<\/li>\n<li>Add a HelloAsso form block or shortcode to a page when needed.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20plugin%20create%20payments%20from%20wordpress%3F\"><h3>Does the plugin create payments from WordPress?<\/h3><\/dt>\n<dd><p>No. The free plugin focuses on connection, retrieval, import, account matching, and form display. Payment checkout remains hosted by HelloAsso.<\/p><\/dd>\n<dt id=\"is%20the%20pro%20add-on%20required%3F\"><h3>Is the Pro add-on required?<\/h3><\/dt>\n<dd><p>No. The free plugin works on its own. The Pro add-on extends it and must be installed alongside the free plugin.<\/p><\/dd>\n<dt id=\"can%20i%20test%20the%20connection%20without%20using%20production%20data%3F\"><h3>Can I test the connection without using production data?<\/h3><\/dt>\n<dd><p>Yes. Select Sandbox and use an organization and API credentials created in the HelloAsso sandbox environment. Production and Sandbox credentials, selected forms, mappings, and locally stored HelloAsso data are kept separate.<\/p><\/dd>\n<dt id=\"does%20switching%20between%20production%20and%20sandbox%20delete%20forms%20or%20imported%20data%3F\"><h3>Does switching between Production and Sandbox delete forms or imported data?<\/h3><\/dt>\n<dd><p>No. Switching environments changes the active connection context. Each environment keeps its own credentials, organization, selected form, mappings, catalog, and transactional data. Returning to an environment restores its previous context.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20support%20several%20helloasso%20organizations%20at%20the%20same%20time%3F\"><h3>Does the plugin support several HelloAsso organizations at the same time?<\/h3><\/dt>\n<dd><p>Version 1.0.0 supports one active HelloAsso organization in Production and one active HelloAsso organization in Sandbox. It does not manage multiple simultaneous organizations inside the same environment.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First public release.<\/li>\n<li>Includes HelloAsso OAuth connection, sandbox support, form discovery, transaction storage, backend CSV export, manual imports, account matching, embeds, privacy tools, display modes, Sprint Club integration, and the public add-on bridge.<\/li>\n<\/ul>","raw_excerpt":"Connect HelloAsso forms and membership data to WordPress, review transactions, import participants, and match user accounts.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/363631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=363631"}],"author":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sprintplugins"}],"wp:attachment":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=363631"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=363631"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=363631"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=363631"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=363631"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=363631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}