First, it is important to understand that an offer (RateBundle) bundles several attributes. Among other things, an offer contains several terms, from which the customer chooses one (Send as rateBundleTermId). An offer can contain e.g. a 6-month term and a 12-month term which differ in price and other features.
Furthermore, it contains modules, e.g. a Drink-Flatrate, which are subdivided into 3 groups:
- Inclusive modules (
modules): Free modules that are always part of the offer (no matter what term is concluded). - Selectable modules (
selectableModules): Free modules from which the customer may choose only a maximum number (maximumNumberOfSelectableModules). - Optional modules (
terms.optionalModules): Paid modules that can be different per term and the customer can choose freely.
Since offers can be configured freely, not all modules must always occur. But every offer must have at least one term.
The flow is usually:
GET /connect/v2/studioGET /connect/v1/rate-bundleDisplay the rate bundle information (Presentation attributes, terms, modules), as well as contract text blocks (see below) to the customer
Submit member and contract data to the preview endpoint to get contract specific preview information
POST /connect/v1/previewSend contract and new member data
POST /connect/v1/rate-bundle
The preview endpoint at
POST /connect/v1/preview
provides information that depends on information specific to the member and selected contract. Currently, the returned DTO contains the following information:
- The contract's pre-use fee
- Information for the voucher to be redeemed, if a voucher code has been provided
- The age-adjusted price dependent on the customer's age, if age-based prices are configured for the rate
- Information on the contract volume. See Total and average prices for online sales for more information
When you want to allow your customers to enter a voucher code, you can use the preview endpoint to fetch information on the voucher, how it changes the prices and to validate the voucher. The returned DTO contains the voucher's properties, which should then be used to visualize the price changes to the customer. If the voucher code is invalid or the voucher cannot be redeemed for another reason, the endpoint sends a 400 Bad Request response.
In the returned DTO, the field voucherType specifies the voucher's type. The types of vouchers that can be redeemed via the Connect API are DISCOUNT and CREDIT.
If the voucher is a discount voucher, the fields
discountValue,discountType,discountedBasePrice,discountedPreviewChargeandomitStarterPackageare set. ThediscountValuedescribes the amount or percentage that is deducted from the rate bundle term's base price. The fielddiscountTypecan either beAMOUNTorPERCENTAGEand determines how thediscountValueshould be interpreted. The fielddiscountedBasePriceis the base price of the specified rate bundle term after the discount has been applied. The fielddiscountedPreviewChargeis the price of the pre-use charge after the discount has been applied. The fieldomitStarterPackagespecifies whether the discount voucher is configured to fully discount the price of the rate bundle term's starter package.If the voucher is a credit voucher, the field
creditValueis set. This field specifies the amount that is credited to the member's account after its creation.
The returned DTO can also contain the properties voucherRemarks and voucherTextBlocks, regardless of the voucher type. The voucherRemarks is a custom text defined in the voucher's configuration. The voucherTextBlocks is a list of ConnectApiSignableTextBlockDtos. These text blocks are configured in the contract document used by the rate bundle term. However, the voucherTextBlocks list does exclusively contain text blocks that are configured to be shown only when a voucher is being redeemed. The list of all other text blocks can be found in the contractTextBlocks property in the rate bundle
To actually redeem the voucher on contract submission, add the voucher code to the voucherCode field in the contract creation request. Only set this field if you know that the voucher code is valid. Otherwise, contract creation will fail.
If configured, the endpoints GET /connect/v1/rate-bundle and POST /connect/v1/preview also return information on the total and average prices during the contract's minimum runtime in the contractVolumeInformation field. This can be configured under Settings -> Membership signing -> Membership signing settings -> Other settings.
For the endpoint GET /connect/v1/rate-bundle, the field is contained in each rate bundle term. For the endpoint POST /connect/v1/preview, the field is present at the top-level. The DTO contains the following information:
- Total contract volume: This is defined as the sum of all payments that are to be performed by the customer during the initial contract runtime. This includes the rate price, the starter package, flat fees, selected modules and the pre-use fee. For example: Assume a contract with a runtime of 4 weeks and a payment frequency of 10 € / week. Assume a starter package of 50 €. This will result in a total contract volume of
((10 €) / week) * 4 weeks + 50 € = 90 €. - Average payment volume per month: This is calculated as follows:
(totalContractVolume / initialContractRuntimeInDays) * DAYS_PER_MONTH. We define1 month = 30 days, thereforeDAYS_PER_MONTH = 30. See below for an example. - Average payment volume per payment frequency term: This is calculated as follows:
(totalContractVolume / initialContractRuntimeInDays) * paymentFrequencyTermInDays. We define1 month = 30 daysand1 year = 365 dayswhen converting the payment frequency term to days. Therefore,paymentFrequencyTermInDays = 365for a payment frequency term of 1 year andpaymentFrequencyTermInDays = 30for a payment frequency term of 1 month. See below for an example. If the payment frequency is 1 month, this is the same as the average payment volume per month.
Please note:
- The assumption that
1 month = 30 dayscauses the following behavior for the average payment volume per month: Assume a contract with a runtime of 1 month. Assume a total contract volume of 10 €. Also assume that the current month (when calling one of the two endpoints that return the contract volume information) has 31 days. The contract volume information calculations always assume that the contract is concluded at the current date. This yields the following payment volume per month:(10 € / 31 days) * 30 days ≈ 9.68 €. However, if the current month has only 30 days, the average payment volume per month is(10 € / 30 days) * 30 days = 10 €. - Similar behavior can occur for the average payment volume per payment frequency term, due to the assumption that
1 year = 365 days. For example: Assume a contract with a runtime of 1 year (during a leapyear) and a payment frequency term of 1 year. Assume a total contract volume of 100 €. This yields an average payment volume per payment frequency term of(100 € / 366 days) * 365 days ≈ 99.73 €. - If there is a pre-use fee, the pre-use period will be added to the contract runtime for the average payment volume calculations. For example: Assume a contract runtime of 2 weeks and a pre-use period of 1 week. Assume that the total contract volume (including pre-use fee) is 15 €. This yields an average payment volume per month of
(15 € / 21 days) * 30 days ≈ 21.43 €. - The contract volume information does not take into account any discounts that may be applied due to the redemption of a voucher.
When creating a new customer with
POST /connect/v1/rate-bundle
you can specify the customer's detailed communication preferences using the communicationPreferences array inside the customer DTO. This array is expected to contain an entry for each message category. Therefore, you need to fetch all message categories first. You can achieve this by fetching a studio's default communication settings:
GET /connect/v1/studio/{studioId}/communication-settings
The list contains an entry for each existing message category. You need to decide for which categories you want to ask the customer for consent. For example, you can match each category by its name.
The rate bundle data eventually contains additional text block information in contractTextBlocks, such as special conditions, house rules or privacy information.
You are advised to display these information to the customer and eventually present him a checkbox for confirmation or a signature:
isConfirmationRequired:true, hasSignature:false- This textblock must be accepted by the user so a mandatory checkbox should be presented.
isConfirmationRequired:true, hasSignature:true- This textblock must be signed by the user so a mandatory signature field should be presented. The signature must be sent back with the id of the textblock in textBlockSignatures
isConfirmationRequired:false, hasSignature:true- This textblock can be signed by the user so a optional signature field should be presented. The signature must be sent back with the id of the textblock in textBlockSignatures
The API supports digital signatures. They will be automatically rendered to the contract document.
If you wish to send them, you have to set them as SVG document in Base 64 Format. The Prefix (data: image/svg+xml;base64,) is optional. Example:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIiB3aWR0aD0iNTMwIiBoZWlnaHQ9IjI0MiIgdmlld0JveD0iMCAwIDUzMCAyNDIiPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxcHgiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0iTSAzNC42NzE4NzUgMTMgTCAzNC42NzE4NzUgMTMgTCAzMy42NzE4NzUgMTMgTCAzMy42NzE4NzUgMTMgTCAzMi42NzE4NzUgMTMgTCAzMi42NzE4NzUgMTQgTCAzMS42NzE4NzUgMTUgTCAyOS42NzE4NzUgMTUgTCAyOC42NzE4NzUgMTYgTCAyNy42NzE4NzUgMTcgTCAyNy42NzE4NzUgMTcgTCAyNi42NzE4NzUgMTcgTCAyNi42NzE4NzUgMTggTCAyNi42NzE4NzUgMTggTCAyNS42NzE4NzUgMTggTCAyNC42NzE4NzUgMTkgTCAyNC42NzE4NzUgMTkgTCAyMy42NzE4NzUgMjAgTCAyMi42NzE4NzUgMjAgTCAyMi42NzE4NzUgMjEgTCAyMS42NzE4NzUgMjEgTCAyMS42NzE4NzUgMjEgTCAyMS42NzE4NzUgMjEgTCAyMS42NzE4NzUgMjEiPjwvcGF0aD48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMXB4IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTkuNjcxODc1IDEwIEwgMTkuNjcxODc1IDEwIEwgMjAuNjcxODc1IDEwIEwgMjAuNjcxODc1IDExIEwgMjAuNjcxODc1IDExIEwgMjAuNjcxODc1IDEyIEwgMjAuNjcxODc1IDEyIEwgMjEuNjcxODc1IDEyIEwgMjEuNjcxODc1IDEyIEwgMjEuNjcxODc1IDEzIEwgMjEuNjcxODc1IDEzIEwgMjEuNjcxODc1IDEzIEwgMjEuNjcxODc1IDEzIEwgMjEuNjcxODc1IDEzIEwgMjEuNjcxODc1IDE0IEwgMjIuNjcxODc1IDE0IEwgMjIuNjcxODc1IDE0IEwgMjIuNjcxODc1IDE1IEwgMjIuNjcxODc1IDE1IEwgMjMuNjcxODc1IDE2IEwgMjMuNjcxODc1IDE2IEwgMjMuNjcxODc1IDE3IEwgMjQuNjcxODc1IDE3IEwgMjQuNjcxODc1IDE3IEwgMjQuNjcxODc1IDE4IEwgMjUuNjcxODc1IDE4IEwgMjUuNjcxODc1IDE5IEwgMjUuNjcxODc1IDE5IEwgMjYuNjcxODc1IDE5IEwgMjYuNjcxODc1IDIwIEwgMjYuNjcxODc1IDIwIEwgMjcuNjcxODc1IDIwIEwgMjcuNjcxODc1IDIxIEwgMjcuNjcxODc1IDIxIEwgMjcuNjcxODc1IDIxIEwgMjguNjcxODc1IDIxIEwgMjguNjcxODc1IDIyIEwgMjguNjcxODc1IDIyIEwgMjguNjcxODc1IDIyIEwgMjkuNjcxODc1IDIyIEwgMjkuNjcxODc1IDIyIj48L3BhdGg+PC9zdmc+The field documentIdentification is a combination of a documentType and a documentNumber. It is a flexible way to store a specific number, e.g. an identification card number.
Following types are available:
- ID_CARD
- PASSPORT
- DRIVERS_LICENSE
- RESIDENCE_PERMIT
- NATIONAL_ID_NUMBER (e.g. for the turkish TC Kimlik number)
There is an automatic validation:
- Both, the
documentTypeand thedocumentNumbermust be filled - For NATIONAL_ID_NUMBER in Turkey there is a validation for the T.C. Kimlik number
The API supports that the user can send a picture which will be used as member-picture in the final customer data. You are advised to use this only for this purpose and no other uploads (like documents etc.) as the image will end up as member picture in the Magicline customer.
Fetch the uploading URL
GET /connect/v1/prospectimage/uploadurlUpload the image you got from the User. This must be implemented by your website code, e.g. access the webcam or provide a file upload. Upload must be a PUT request with the **binary data ** (not JSON, base64 or anything else) of the file, like described here, against the provided UploadUrl.
Send the
objectKey, you fetch together with the uploadUrl, as
imageObjectKeyin the final
POST /connect/v1/rate-bundleDuring the process of member creation the given
imageObjectKeywill be checked and the corresponding data which should be accessible behind it load and used as member picture. If something fails a 500 response will be returned with
{ "message": "Invalid image format", "errorCodes": [ "VALIDATION_FAILED" ] }You must make sure that the upload request has finished before you send the final POST request otherwise it would fail because the file cannot be copied!
In some countries there is a legal obligation to allow contract cancellations online without the customer having to log in.
We provide a whitelabel solution for that so that you just need to add a link to your page with a URL of this pattern:
https://public.magicline.com/#/contractTermination?tenant=<tenant_name>&studio=<studio_id>
Both parameters are mandatory and need to be set. The tenant name value is the same one you need to access the API. The studio ID needs to be set to preload specific information of that studio and preselect it in the studio select box. The URL leads to a page where a member can search for their contract(s) and submit the cancellation.
If you want to use your own page instead of the whitelabel one, you can do so by implementing an invisible reCAPTCHA challenge on your site. Please contact customer support first, so we can activate your domain for reCAPTCHA. The site key required to set up reCAPTCHA is 6Ld5qKcgAAAAAMoywArOgIrC0lQ7NpYUTsF92PIC. Generate a token and set the query parameter recaptchaToken where required.
Note: A token is only valid for two minutes. Make sure the challenge is not invoked too early.
Example:
First, fetch all studios with their basic information.
GET /connect/v1/contracts/studiosRetrieve all active contracts for a member. If a member forgot their customer number, skip to step 5.
POST /connect/v1/contractsFetch studios cancellation information for the member's studio to get possible cancellation reasons. The member's studio ID can be found in the response of the previous step's request. The response is a list of contracts and each contract has a field containing the member's studio's ID. The ID is the same for each contract, so you can just use the studio's ID from the first element in the list.
GET /connect/v1/contracts/studios/{studioId}Submit the cancellation for the contract the member wishes to cancel.
POST /connect/v1/contracts/cancelIf the member forgot their customer number, you can let them submit a manual cancellation request. Therefore, let the member select a studio from the fetched list in step 1. Then load the
cancellation reasons (deprecated)for that studio.GET /connect/v1/contracts/studios/{studioId}/cancellation-reasonsFinally, submit the manual cancellation request.
POST /connect/v1/contracts/cancel-requestInstead of immediately cancelling a contract, the manual cancellation request will create a task in the Magicline for the studio that has been selected by the customer.
If a gym has a payment method such as credit card set up for an offer, the payment is handled through the Universal Payment Component (UPC). The UPC is an embeddable payment widget that securely guides the user through the payment flow and produces a paymentRequestToken that you send when creating the contract.
For full details on the UPC widget integration, configuration, and styling, see the Working with Payment API documentation.
Create a user payment session
Fetch a short-lived session token from the Connect API:
POST /connect/v1/payment/user-payment-sessionLaunch the UPC widget
Use the session token to initialize the UPC widget in your frontend. The widget presents the available payment methods to the user and handles the entire payment authorization flow.
Receive the payment request token
Once the user completes the payment flow in the widget, the UPC returns a
paymentRequestTokenvia theonSuccesscallback.Submit the contract
Include the
paymentRequestTokenin the request body when calling the contract creation endpoint:POST /connect/v1/rate-bundle