Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Shells Virtual Desktop
BMail.ag - Secure Email Service
Server.net
CPLicense.net
VPS Server
Buy VPN
Vultr
VMs for AI
HostDare
ReliableSite White-Label Dedicated Hosting for Resellers
InterServer VPS
BMail.ag - Secure Email Service
Best VPN
High-Performance Bare Metal Server Solutions
Karvl.com
Server Mania Cloud Hosting
DataWagon Hosting
AlphaVPS Hosting
Evoxt.com
Clouvider
VPS Hosting with NVMe
Residential IPs in the US & 4G Mobile Proxies in EU & US with Unlimited Bandwidth
ReliableSite White-Label Dedicated Hosting for Resellers
Rabisu - Hosting Solutions
Shells Virtual Desktop
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

[Dispute] Host-C Pioneer 5TB EOL: Shifting Dates, Messy Math, and Ninja Billing Changes

124

Comments

  • @JasonJohn said:

    @jsg said:
    Put your Karen wah-wah in bold as much as you like, the major evidence I see here is that you are an MJJ and an

    asshole!

    Please continue with your discrimination and profanity.

    Facts speak louder than words — it is as simple as that.

    I am trying to understand the end goal here.

    What you are trying to achieve? Do you want that $1 or whatever as a refund or do you want to revolutionise the industry since it works on different standards (allegedly)? Or do you want an apology from the provider?

    Right now, you are arguing just for the sake of arguing (as it seems). So what do you want?

  • edited May 3

    @JasonJohn said:

    @rpqu said:

    @JasonJohn said:
    Addendum: There is one more question — why is I125 calculated based on 34 days, while I185 is calculated based on 33 days? This is precisely evidence of Host-C's chaotic billing system.

    Perhaps because you bought it at different HH:mm:ss?

    Yes, the purchase dates are different, but in Ticket GNK-260844, I requested that the expiration dates of both services be unified, and I paid the corresponding fee. Host-C made the adjustment accordingly, and the Next Due Date under My Products & Services reflects the same. So why is that the case?


    Service Status: Proof that both instances expire on June 3, 2026.



    Hello @JasonJohn (is that John Jason or Jason John by the way?) i feel your loss but at the same time i can't help but see how your efforts are very much futile at this point.

    By now this thread has likely incurred you lost revenue multiple times the amount of money being fought over while the world economy easily shrunk by some 3 digit sum over wasted energy costs and again lost revenue (people playing algebra FBI can't sell carrots on the local market or whatever the average LET user does for a living).

    All of this for the final conclusion that a host might have made some kind of rounding error or even genuine mistake during the calculation of remaining days on a pro rated refund amounting to a contested difference of literal cents.

    Not only is there not even a vague relation to the amount of costs involved of pursuing this matter but the percentage of onlookers likely to give even two single shits is also practically zero. That obviously excludes people who incurred a pumping headache trying to follow this thread but then those are even more unlikely to be sympathetic to your issues.

    Given these profound circumstances i kindly advise you to leave it be.

    Sincerely
    A concerned citizen

    Thanked by 2zed oloke
  • JasonJohnJasonJohn Member

    @rpqu said: If that's the case, I would advise you to make excel spreadsheet/gdocs or simple script to reproduce the calculation.

    Thank you for your reply. I will organize the current situation shortly and fully express my requests.

    @rpqu said: Also, why do you agree to overpay by 2.9896% on the extension (adjusted after PayPal cut).

    To be honest, at the time, I trusted Host-C's billing system and did not think too much about it. Besides, the amount was not large, and the price was not far from what I had expected — roughly three-quarters, which would be around 33.75 (45 ÷ 4 × 3).

  • ascicodeascicode Member

    @angstrom Think all have been said.

  • JasonJohnJasonJohn Member
    edited May 3

    I apologize to the LET community for the disorganized presentation earlier. Thank you for reading this far, and I appreciate your time. :)

    • The following facts need to be emphasized once again:
    1. The EOL date is April 30, 2026, and the refund start date is May 1st. Both services I185 and I125 have an expiration date of June 3, 2026, making the number of days for refund calculation 34 days.


      Screenshot of the EOL announcement.





      Screenshot of the expiration dates of both services.



    2. The announcement of the significantly advanced EOL date was published on Host-C's website on March 1, 2026, which is after both services had already been paid for. Due to the significant advancement of the EOL date, partial refunds are required for both services.


      Screenshots of the billing payment records for both services within the Host-C website.





      Screenshots of the billing payment records for both services on PayPal.




    3. I125 was obtained through a transaction with another party, and the transfer was completed via Host-C's ticket system. The status of the service at the time of transfer was: renewal price of 12.50 USD billed quarterly, with an expiration date of September 25, 2025. Ticket #VWB-555299 - Transfer Request.


      Screenshot of Ticket #VWB-555299 - Transfer Request (I am currently unable to obtain a complete screenshot, as Host-C has revoked my ticket access).





      Screenshot of the status of service I125 at the time of transfer.



    4. I125 was switched from quarterly to annual billing under Ticket #GNK-260844 - Apply to switch to annual payment. In the ticket reply dated July 9, 2025, two amounts were explicitly stated: a remaining balance of 11.96 USD on service I125, and an additional payment of 32.42 USD required to switch to annual billing and extend the service to June 3, 2026.


      Screenshot of Ticket #GNK-260844 - Apply to switch to annual payment.



    5. Host-C considers the remaining value of I185 to be 4.09 USD and the remaining value of I125 to be 3.35 USD, and holds that the PayPal transaction fees should be borne by me. The calculation formula explicitly stated in this thread is: Refund Amount = (Service Price ÷ Total Service Days) × Remaining Days.


      Screenshot of Ticket #VIC-136421 - Service Refund Confirmation.



      @host_c said: @JasonJohn
      You got the cash back with no fees on our part, so whatever alse landed with you, take it up with whomever was paying for the services on your behalf, if that is not the case, take it up with PP.
      @host_c said: For pro-rated services, I doubt that there is other formulas then:
      Refund Amount = (Service Price ÷ Total Service Days) × Remaining Days

    • The following are my requests:
    1. The remaining value of service I185 is incorrect and should be 45 ÷ 365 × 34 = 4.19 USD.

    2. The remaining value of service I125 is incorrect. There are two possible calculation methods: ① Based on the annual fee of 45 USD, the remaining value would be the same as that of service I185, which is 4.19 USD; ② Based on the top-up payment of 32.42 USD, the calculation would be 32.42 ÷ 251 × 34 = 4.39 USD. (The 251 days refers to the period from September 26, 2025 to June 3, 2026, calculated as 5+31+30+31+31+28+31+30+31+3=251.)

    3. Since the significant advancement of the EOL date has necessitated partial refunds for both services, the PayPal transaction fees should be borne by Host-C, and the increase in my PayPal available balance should be consistent with the remaining value of both services.

    4. Return the two refunds already received via the original payment method, or have Host-C initiate a new payment to make up the difference.

    • Regarding requirement 2, if Host-C disagrees with both calculation methods, please provide: ① the calculation formula used to arrive at the remaining value of 3.35 USD for service I125; ② a detailed explanation of the specific calculation formulas used for the two amounts (11.96 USD and 32.42 USD) in the ticket for switching service I125 from quarterly to annual billing (Ticket #GNK-260844 - Apply to switch to annual payment).

    I apologize to the LET community for the disorganized presentation earlier. Thank you for reading this far, and I appreciate your time. :)

  • @JasonJohn said:
    I apologize to the LET community for the disorganized presentation earlier. Thank you for reading this far, and I appreciate your time. :)

    • The following facts need to be emphasized once again:
    1. The EOL date is April 30, 2026, and the refund start date is May 1st. Both services I185 and I125 have an expiration date of June 3, 2026, making the number of days for refund calculation 34 days.


      Screenshot of the EOL announcement.





      Screenshot of the expiration dates of both services.



    2. The announcement of the significantly advanced EOL date was published on Host-C's website on March 1, 2026, which is after both services had already been paid for. Due to the significant advancement of the EOL date, partial refunds are required for both services.


      Screenshots of the billing payment records for both services within the Host-C website.





      Screenshots of the billing payment records for both services on PayPal.




    3. I125 was obtained through a transaction with another party, and the transfer was completed via Host-C's ticket system. The status of the service at the time of transfer was: renewal price of 12.50 USD billed quarterly, with an expiration date of September 25, 2025. Ticket #VWB-555299 - Transfer Request.


      Screenshot of Ticket #VWB-555299 - Transfer Request (I am currently unable to obtain a complete screenshot, as Host-C has revoked my ticket access).





      Screenshot of the status of service I125 at the time of transfer.



    4. I125 was switched from quarterly to annual billing under Ticket #GNK-260844 - Apply to switch to annual payment. In the ticket reply dated July 9, 2025, two amounts were explicitly stated: a remaining balance of 11.96 USD on service I125, and an additional payment of 32.42 USD required to switch to annual billing and extend the service to June 3, 2026.


      Screenshot of Ticket #GNK-260844 - Apply to switch to annual payment.



    5. Host-C considers the remaining value of I185 to be 4.09 USD and the remaining value of I125 to be 3.35 USD, and holds that the PayPal transaction fees should be borne by me. The calculation formula explicitly stated in this thread is: Refund Amount = (Service Price ÷ Total Service Days) × Remaining Days.


      Screenshot of Ticket #VIC-136421 - Service Refund Confirmation.



      @host_c said: @JasonJohn
      You got the cash back with no fees on our part, so whatever alse landed with you, take it up with whomever was paying for the services on your behalf, if that is not the case, take it up with PP.
      @host_c said: For pro-rated services, I doubt that there is other formulas then:
      Refund Amount = (Service Price ÷ Total Service Days) × Remaining Days

    • The following are my requests:
    1. The remaining value of service I185 is incorrect and should be 45 ÷ 365 × 34 = 4.19 USD.

    2. The remaining value of service I125 is incorrect. There are two possible calculation methods: ① Based on the annual fee of 45 USD, the remaining value would be the same as that of service I185, which is 4.19 USD; ② Based on the top-up payment of 32.42 USD, the calculation would be 32.42 ÷ 251 × 34 = 4.39 USD. (The 251 days refers to the period from September 26, 2025 to June 3, 2026, calculated as 5+31+30+31+31+28+31+30+31+3=251.)

    3. Since the significant advancement of the EOL date has necessitated partial refunds for both services, the PayPal transaction fees should be borne by Host-C, and the increase in my PayPal available balance should be consistent with the remaining value of both services.

    4. Return the two refunds already received via the original payment method, or have Host-C initiate a new payment to make up the difference.

    • Regarding requirement 2, if Host-C disagrees with both calculation methods, please provide: ① the calculation formula used to arrive at the remaining value of 3.35 USD for service I125; ② a detailed explanation of the specific calculation formulas used for the two amounts (11.96 USD and 32.42 USD) in the ticket for switching service I125 from quarterly to annual billing (Ticket #GNK-260844 - Apply to switch to annual payment).

    I apologize to the LET community for the disorganized presentation earlier. Thank you for reading this far, and I appreciate your time. :)

    Give the total.

  • JasonJohnJasonJohn Member

    @rpqu said:
    If that's the case, I would advise you to make excel spreadsheet/gdocs or simple script to reproduce the calculation.

    Hello, could you please help me check whether there are any logical errors or expression errors in this post? Thank you for your help. :)

  • eliphaseliphas Member

    Thanked by 1jsg
  • JasonJohnJasonJohn Member

    @itachikonoha said:
    Give the total.

    Thank you for your reply.

    In fact, the amount involved in this dispute is very small. My reason for posting on LET is not about the money itself, but rather about what I believe to be Host-C's incorrect method of calculating the remaining value in their billing system, and the fact that they have persistently refused to acknowledge the error when I pointed it out. Many other users who are also due refunds will likewise be affected by what I believe to be this incorrect calculation. Business transactions should be conducted with integrity — neither more nor less, but exactly the right amount.

    At the same time, I would like this thread to remain open, or alternatively, Host-C commits to handling refunds for users affected by this EOL and any future refund cases in accordance with the requirements I have put forward.

    I have already laid out the complete facts and expressed the reasoning clearly. I can list the total amount, but the final figure ultimately rests with Host-C.

    • PayPal's transaction fee is 4.4% of the amount sent plus 0.30 USD.

    • If calculated using Method ① under Requirement 2:
      I return the two transfers already received, and Host-C initiates a new transfer of 9.08 USD;
      Or
      I do not need to return the transfers, and Host-C initiates an additional transfer of 2.29 USD;

    • If calculated using Method ② under Requirement 2:
      I return the two transfers already received, and Host-C initiates a new transfer of 9.29 USD;
      Or
      I do not need to return the transfers, and Host-C initiates an additional transfer of 2.50 USD;

  • Thanked by 2host_c eliphas
  • jsgjsg Member, Resident Benchmarker

    @JasonJohn said:
    [A pile of BS]

    Thanks but I - and certainly others - did not even read your new BS version.

    @host_c, no matter your Karen noise, was, is, and stays the #1 top storage provider

  • rpqurpqu Member
    edited May 3

    @JasonJohn said:

    @rpqu said:
    If that's the case, I would advise you to make excel spreadsheet/gdocs or simple script to reproduce the calculation.

    Hello, could you please help me check whether there are any logical errors or expression errors in this post? Thank you for your help. :)

    Sigh. I said please make spreadsheet so everyone could understand.

    (Claude's extrapolation)

    Service retired: 2026-04-30 | Both servers: $45/year


    Server A

    Paid $45.00 (host net $42.24 after $2.76 PayPal fee)
    Billing period 2025-07-03 → 2026-07-03 (365 days)
    Remaining days 33 days (May 1 → Jul 3, counted from May 1)
    Refund formula (33/365) × $45.00 = $4.07
    Received $4.07 ✓

    Server B

    Pre-existing credit $11.96 (no PayPal fee)
    New payment $32.42 (host net $30.31 after $2.11 PayPal fee)
    Total paid $44.38
    Total host net $42.27
    Billing period 2025-07-09 → 2026-06-03 (329 days)
    Remaining days 34 days (Apr 30 → Jun 3)
    Received $3.35

    The Error

    The host prorated on $32.42 only, ignoring the $11.96 credit.

    Calculation Amount
    Host's (wrong): (34/329) × $32.42 $3.35
    Correct (gross): (34/329) × $44.38 $4.59
    Correct (net): (34/329) × $42.27 $4.37
    Shortfall $1.02 – $1.24

    Summary

    Correct (gross) Correct (net) Received
    Server A $4.07 $4.07 ✓
    Server B $4.59 $4.37 $3.35 ✗
    Total $8.65 $8.44 $7.42
    Shortfall $1.23 $1.02

    Dispute basis: The $11.96 pre-existing credit was applied toward Server B's 2025-07-09 → 2026-06-03 period but was excluded from the refund base amount. The host's own formula is correct — only the input amount ($32.42 vs $44.38) is wrong.

    Reproducible calculation
    """
    Hosting Service Early Retirement — Refund Verification
    =======================================================
    
    Background
    ----------
    The customer holds two annual servers at $45/year each.
    
      Server A  – billing cycle July 3; last renewal July 3, 2025.
    
      Server B  – original cycle May 24. On 2025-07-09 the customer had a
                  remaining credit balance of $11.96 from the old cycle.
                  Support charged an additional $32.42 (via PayPal) to migrate
                  and extend the cycle, setting the new renewal at 2026-06-03.
                  Total paid toward the new period: $11.96 + $32.42 = $44.38.
    
    The host retired the service on 2026-04-30, issuing partial refunds:
      Server A  → $4.07 received
      Server B  → $3.35 received
    
    PayPal transaction fees (non-refundable to the host):
      $45.00  → host net $42.24  (PayPal kept $2.76)  [Server A]
      $32.42  → host net $30.31  (PayPal kept $2.11)  [Server B new payment only]
      $11.96  → already net; no additional PayPal fee (pre-existing credit)
      Server B total host net: $11.96 + $30.31 = $42.27
    
    Proration formula (confirmed from Server A)
    --------------------------------------------
      refund = (remaining_days / service_period_days) × gross_amount_paid
    
      Server A: remaining = May 1 → Jul 3, 2026 = 33 days (host's count, accepted)
                period    = Jul 3, 2025 → Jul 3, 2026 = 365 days
                refund    = (33 / 365) × $45.00 = $4.07  ✓
    
      Note: the retirement date (Apr 30) is treated as fully used; remaining
      days are counted from May 1 onward.
    
    Server B — the error
    ----------------------
      The host prorated only on the $32.42 new PayPal payment, ignoring the
      $11.96 credit that was also applied toward this service period.
    
      Host's (wrong) calc: (34 / 329) × $32.42 = $3.35
      Correct calc:        (34 / 329) × $44.38  = $4.59   (gross, incl. credit)
                           (34 / 329) × $42.27  = $4.37   (net,   incl. credit)
    
      Shortfall (gross basis): $4.59 − $3.35 = $1.24
      Shortfall (net   basis): $4.37 − $3.35 = $1.02
    
      Note: remaining = Apr 30 → Jun 3 = 34 days. Server A's formula starts from
      May 1 (33 days to Jun 3), but the same reasoning applied to Server B using
      the same off-by-one would give (33/329) × $44.38 = $4.45, shortfall $1.10.
      The most defensible figure is the gross-basis $4.59 (host's own formula,
      correct base amount).
    
    To answer the explicit question: yes, the host DID use 365 as divisor for
    Server A (because the paid period IS 365 days for an annual plan). For
    Server B they correctly used 329 (the actual paid period), but applied it to
    $32.42 instead of $44.38. Using a flat 365 for Server B would give
    (34/365) × $44.38 = $4.13 — slightly different but still more than $3.35.
    """
    
    from datetime import date
    
    # ─── Key dates ────────────────────────────────────────────────────────────────
    SERVER_A_BILLING_START = date(2025, 7, 3)
    SERVER_A_BILLING_END   = date(2026, 7, 3)
    
    SERVER_B_PAYMENT_DATE  = date(2025, 7, 9)
    SERVER_B_BILLING_END   = date(2026, 6, 3)
    
    SERVICE_RETIRED   = date(2026, 4, 30)
    FIRST_UNUSED_DAY  = date(2026, 5, 1)   # host treats Apr 30 as last used day
    
    # ─── Server A payments ────────────────────────────────────────────────────────
    A_GROSS   = 45.00
    A_PP_FEE  =  2.76
    A_NET     = A_GROSS - A_PP_FEE          # 42.24
    
    # ─── Server B payments ────────────────────────────────────────────────────────
    B_CREDIT      = 11.96                   # pre-existing balance, no new PayPal fee
    B_NEW_PAYMENT = 32.42
    B_PP_FEE      =  2.11
    B_NEW_NET     = B_NEW_PAYMENT - B_PP_FEE  # 30.31
    B_GROSS_TOTAL = B_CREDIT + B_NEW_PAYMENT  # 44.38  ← what the customer actually paid
    B_NET_TOTAL   = B_CREDIT + B_NEW_NET      # 42.27  ← what the host actually kept
    
    # ─── What the customer received ───────────────────────────────────────────────
    A_RECEIVED = 4.07
    B_RECEIVED = 3.35
    
    # ─── Service periods ──────────────────────────────────────────────────────────
    a_period = (SERVER_A_BILLING_END - SERVER_A_BILLING_START).days   # 365
    b_period = (SERVER_B_BILLING_END - SERVER_B_PAYMENT_DATE ).days   # 329
    
    # ─── Remaining unused days ────────────────────────────────────────────────────
    # Server A: host counted from May 1 (33 days to Jun 3) — accepted as correct.
    # Server B: host counted from Apr 30 (34 days to Jun 3) — one day earlier,
    #           but the base-amount error is the main issue we focus on.
    a_remaining = (SERVER_B_BILLING_END - FIRST_UNUSED_DAY).days   # 33  (host's own count)
    b_remaining = (SERVER_B_BILLING_END - SERVICE_RETIRED  ).days   # 34
    
    # ─── Refund calculations ──────────────────────────────────────────────────────
    
    # Server A — accepted as correct by customer
    a_correct = (a_remaining / a_period) * A_GROSS             # 4.07
    
    # Server B — host's (wrong) calculation: forgot the $11.96 credit
    b_host_wrong = (b_remaining / b_period) * B_NEW_PAYMENT    # 3.35  ← what was paid
    
    # Server B — correct calculations
    b_correct_gross = (b_remaining / b_period) * B_GROSS_TOTAL  # 4.59  (gross basis)
    b_correct_net   = (b_remaining / b_period) * B_NET_TOTAL    # 4.37  (net basis)
    
    # ─── Report ───────────────────────────────────────────────────────────────────
    W = 58
    SEP = "─" * W
    
    print("═" * W)
    print("  SERVER A")
    print("═" * W)
    print(f"  Paid (gross):                   ${A_GROSS:>6.2f}")
    print(f"  Host received (net):            ${A_NET:>6.2f}  (PayPal kept ${A_PP_FEE:.2f})")
    print(f"  Service period:                 {a_period} days")
    print(f"  Remaining unused days:          {a_remaining} days  (May 1 → Jul 3, 2026)")
    print(SEP)
    print(f"  Refund = ({a_remaining}/{a_period}) × ${A_GROSS:.2f}  =  ${a_correct:.2f}")
    print(f"  Received:                       ${A_RECEIVED:.2f}  ✓  (matches)")
    print()
    
    print("═" * W)
    print("  SERVER B")
    print("═" * W)
    print(f"  Pre-existing credit:            ${B_CREDIT:>6.2f}  (no PayPal fee)")
    print(f"  New PayPal payment (gross):     ${B_NEW_PAYMENT:>6.2f}")
    print(f"  PayPal fee on new payment:      ${B_PP_FEE:>6.2f}")
    print(f"  Host net from new payment:      ${B_NEW_NET:>6.2f}")
    print(f"  Total paid by customer:         ${B_GROSS_TOTAL:>6.2f}  (credit + new payment)")
    print(f"  Total host received (net):      ${B_NET_TOTAL:>6.2f}  (credit + net payment)")
    print(f"  Service period:                 {b_period} days  (Jul 9, 2025 → Jun 3, 2026)")
    print(f"  Remaining unused days:          {b_remaining} days  (Apr 30 → Jun 3, 2026)")
    print(SEP)
    print(f"  Host's (wrong) refund:   ({b_remaining}/{b_period}) × ${B_NEW_PAYMENT:.2f}  =  ${b_host_wrong:.2f}")
    print(f"    ↳ Error: credit (${B_CREDIT:.2f}) not included in the base amount")
    print(SEP)
    print(f"  Correct refund (gross):  ({b_remaining}/{b_period}) × ${B_GROSS_TOTAL:.2f} =  ${b_correct_gross:.2f}")
    print(f"  Correct refund (net):    ({b_remaining}/{b_period}) × ${B_NET_TOTAL:.2f} =  ${b_correct_net:.2f}")
    print(SEP)
    print(f"  Received:                       ${B_RECEIVED:.2f}")
    print(f"  Shortfall (gross basis):        ${b_correct_gross - B_RECEIVED:.2f}")
    print(f"  Shortfall (net   basis):        ${b_correct_net   - B_RECEIVED:.2f}")
    print()
    
    print("═" * W)
    print("  TOTAL SUMMARY")
    print("═" * W)
    total_correct_gross = a_correct + b_correct_gross
    total_correct_net   = a_correct + b_correct_net
    total_received      = A_RECEIVED + B_RECEIVED
    print(f"  Total correct refund (gross):   ${total_correct_gross:.2f}")
    print(f"  Total correct refund (net):     ${total_correct_net:.2f}")
    print(f"  Total actually received:        ${total_received:.2f}")
    print(f"  Total shortfall (gross):        ${total_correct_gross - total_received:.2f}")
    print(f"  Total shortfall (net):          ${total_correct_net   - total_received:.2f}")
    

    The script to avoid this edge case
    #!/usr/bin/env python3
    """
    Prorated Refund Calculator
    Computes the correct refund when a service is terminated before the billing period ends.
    Handles optional billing realignment (cycle migration with pre-existing credit).
    """
    
    import calendar
    from datetime import date, datetime, timedelta
    
    # ─── Helpers ──────────────────────────────────────────────────────────────────
    
    def add_months(d, n):
        month = d.month - 1 + n
        year  = d.year + month // 12
        month = month % 12 + 1
        day   = min(d.day, calendar.monthrange(year, month)[1])
        return date(year, month, day)
    
    def parse_date(s):
        return date.fromisoformat(s.strip())
    
    def parse_datetime(s):
        s = s.strip()
        try:
            return datetime.fromisoformat(s)
        except ValueError:
            # accept plain date → midnight
            return datetime.combine(date.fromisoformat(s), datetime.min.time())
    
    def ask(prompt, default=None):
        suffix = f" [{default}]" if default is not None else ""
        val = input(f"  {prompt}{suffix}: ").strip()
        return val if val else (str(default) if default is not None else "")
    
    def ask_float(prompt, default=0.0):
        raw = ask(prompt, default)
        try:
            return float(raw)
        except ValueError:
            print("    Invalid number, using 0.00")
            return 0.0
    
    def ask_date(prompt):
        while True:
            raw = input(f"  {prompt} [YYYY-MM-DD]: ").strip()
            try:
                return parse_date(raw)
            except ValueError:
                print("    Invalid date. Use YYYY-MM-DD.")
    
    def ask_datetime(prompt):
        while True:
            raw = input(f"  {prompt} [YYYY-MM-DD or YYYY-MM-DD HH:MM]: ").strip()
            try:
                return parse_datetime(raw)
            except ValueError:
                print("    Invalid. Use YYYY-MM-DD or YYYY-MM-DD HH:MM.")
    
    def ask_yesno(prompt, default="y"):
        raw = input(f"  {prompt} [{'Y/n' if default=='y' else 'y/N'}]: ").strip().lower()
        if not raw:
            return default == "y"
        return raw.startswith("y")
    
    CYCLES = [
        ("1",  "hourly",      "1 hour"),
        ("2",  "daily",       "1 day"),
        ("3",  "weekly",      "7 days"),
        ("4",  "fortnightly", "14 days"),
        ("5",  "monthly",     "1 calendar month"),
        ("6",  "quarterly",   "3 calendar months"),
        ("7",  "semi-annual", "6 calendar months"),
        ("8",  "yearly",      "1 year  (enter N for multi-year)"),
    ]
    
    def ask_cycle():
        print()
        print("  Billing cycles:")
        for num, name, desc in CYCLES:
            print(f"    {num}. {name:<13} ({desc})")
        while True:
            raw = input("  Choose [1-8] or name: ").strip().lower()
            if raw.isdigit():
                idx = int(raw) - 1
                if 0 <= idx < len(CYCLES):
                    return CYCLES[idx][1]
            else:
                for _, name, _ in CYCLES:
                    if raw == name:
                        return name
            print("    Invalid choice.")
    
    def cycle_end_date(start, cycle, n_years=1):
        """Return the end date (exclusive — the next billing date) for a cycle."""
        if cycle == "daily":      return start + timedelta(days=1)
        if cycle == "weekly":     return start + timedelta(weeks=1)
        if cycle == "fortnightly":return start + timedelta(weeks=2)
        if cycle == "monthly":    return add_months(start, 1)
        if cycle == "quarterly":  return add_months(start, 3)
        if cycle == "semi-annual":return add_months(start, 6)
        if cycle == "yearly":     return add_months(start, 12 * n_years)
        return None  # hourly handled separately with datetime
    
    def cycle_end_datetime(start_dt, cycle):
        """Datetime variant for hourly cycles."""
        return start_dt + timedelta(hours=1)
    
    # ─── Main ─────────────────────────────────────────────────────────────────────
    
    def main():
        HR  = "─" * 52
        HR2 = "═" * 52
    
        print(HR2)
        print("  Prorated Refund Calculator")
        print(HR2)
    
        hourly = False  # flag for datetime-based path
    
        # ── Section 1: original service ───────────────────────────────────────────
        print()
        print("[1] Original Service")
        print(HR)
    
        cycle = ask_cycle()
        n_years = 1
        if cycle == "yearly":
            raw_n = ask("Number of years", 1)
            n_years = int(raw_n) if str(raw_n).isdigit() else 1
            if n_years > 1:
                print(f"    → Cycle: {n_years}-year")
    
        if cycle == "hourly":
            hourly = True
            service_start_dt = ask_datetime("Service start date/time")
            orig_end_dt      = cycle_end_datetime(service_start_dt, cycle)
            period_seconds   = (orig_end_dt - service_start_dt).total_seconds()
            print(f"    → Period: {service_start_dt} → {orig_end_dt} ({period_seconds/3600:.2f} hrs)")
        else:
            service_start = ask_date("Service start date")
            orig_end      = cycle_end_date(service_start, cycle, n_years)
            period_days   = (orig_end - service_start).days
            print(f"    → Period: {service_start} → {orig_end} ({period_days} days)")
    
        gross = ask_float("Amount paid (gross) $")
        fee   = ask_float("Payment processor fee $", 0.0)
        net   = gross - fee
        print(f"    → Host receives: ${net:.2f}")
    
        # ── Section 2: realignment ────────────────────────────────────────────────
        print()
        print("[2] Billing Realignment (skip if none)")
        print(HR)
    
        has_realign = ask_yesno("Was there a billing realignment?", default="n")
    
        if has_realign:
            if hourly:
                realign_dt = ask_datetime("Realignment date/time")
            else:
                realign_date = ask_date("Realignment date")
    
            credit    = ask_float("Pre-existing credit applied $", 0.0)
            new_gross = ask_float("New payment (gross) $")
            new_fee   = ask_float("Payment processor fee on new payment $", 0.0)
            new_net   = new_gross - new_fee
    
            if hourly:
                new_end_dt      = ask_datetime("New billing end date/time")
                period_seconds  = (new_end_dt - realign_dt).total_seconds()
                print(f"    → New period: {realign_dt} → {new_end_dt} ({period_seconds/3600:.2f} hrs)")
            else:
                new_end      = ask_date("New billing end date")
                period_start = realign_date
                period_end   = new_end
                period_days  = (period_end - period_start).days
                print(f"    → New period: {period_start} → {period_end} ({period_days} days)")
    
            total_gross = credit + new_gross
            total_net   = credit + new_net
            print(f"    → Total paid (credit + new payment): ${total_gross:.2f}")
            print(f"    → Total host net:                    ${total_net:.2f}")
    
        else:
            credit      = 0.0
            total_gross = gross
            total_net   = net
            if not hourly:
                period_start = service_start
                period_end   = orig_end
    
        # ── Section 3: cessation ──────────────────────────────────────────────────
        print()
        print("[3] Service Cessation")
        print(HR)
    
        if hourly:
            cessation_dt     = ask_datetime("Cessation date/time")
            count_cessation  = ask_yesno("Count cessation time onward as unused?", default="y")
            remaining_start_dt = cessation_dt if count_cessation else cessation_dt + timedelta(hours=1)
            end_dt             = new_end_dt if has_realign else orig_end_dt
            remaining_seconds  = (end_dt - remaining_start_dt).total_seconds()
            remaining_hours    = remaining_seconds / 3600
    
            if remaining_seconds <= 0:
                print("\n  No remaining time — no refund due.")
                return
    
            refund_gross = (remaining_seconds / period_seconds) * total_gross
            refund_net   = (remaining_seconds / period_seconds) * total_net
    
            print()
            print(HR2)
            print("  RESULTS")
            print(HR2)
            end_display   = new_end_dt if has_realign else orig_end_dt
            start_display = realign_dt if has_realign else service_start_dt
            print(f"  Service period:          {start_display} → {end_display}")
            print(f"  Period length:           {period_seconds/3600:.4f} hours")
            print(f"  Remaining unused:        {remaining_hours:.4f} hours")
            print(f"  Total paid (gross):      ${total_gross:.2f}")
            print(f"  Total host net:          ${total_net:.2f}")
            print(HR)
            print(f"  Formula: ({remaining_hours:.4f}h / {period_seconds/3600:.4f}h) × amount")
            print(f"  Correct refund (gross):  ${refund_gross:.2f}")
            print(f"  Correct refund (net):    ${refund_net:.2f}")
    
        else:
            cessation        = ask_date("Service cessation (retirement) date")
            count_cessation  = ask_yesno("Count cessation date as unused?", default="y")
    
            end_display   = period_end   if has_realign else orig_end
            start_display = period_start if has_realign else service_start
            p_days        = period_days  if has_realign else (orig_end - service_start).days
    
            remaining_from = cessation if count_cessation else cessation + timedelta(days=1)
            remaining_days = (end_display - remaining_from).days
    
            if remaining_days <= 0:
                print("\n  No remaining days — no refund due.")
                return
    
            refund_gross = (remaining_days / p_days) * total_gross
            refund_net   = (remaining_days / p_days) * total_net
    
            print()
            print(HR2)
            print("  RESULTS")
            print(HR2)
            print(f"  Service period:          {start_display} → {end_display}")
            print(f"  Period length:           {p_days} days")
            print(f"  Remaining unused days:   {remaining_days}  ({remaining_from} → {end_display})")
            print(f"  Total paid (gross):      ${total_gross:.2f}")
            print(f"  Total host net:          ${total_net:.2f}")
            print(HR)
            print(f"  Formula: ({remaining_days}/{p_days}) × amount")
            print(f"  Correct refund (gross):  ${refund_gross:.2f}")
            print(f"  Correct refund (net):    ${refund_net:.2f}")
    
        print()
    
    if __name__ == "__main__":
        main()
    

    Btw, @host_c that costs me $0.88

    @JasonJohn Please use AI for more than translation. Pointing out the error is the easiest way to receive the acknowledgement.
    All of this for $1.02-$1.24 of refund

  • I have brought out the bla bla bla script again.

    Thanked by 1host_c
  • rpqurpqu Member

    bla bla bla

  • JasonJohnJasonJohn Member
    edited May 3

    @rpqu said: @JasonJohn Please use AI for more than translation. Pointing out the error is the easiest way to receive the acknowledgement.

    Indeed, a table is much easier to understand. Thank you for the clear table presentation.

    @rpqu said: All of this for $1.02-$1.24 of refund

    I have already replied above — this is not a matter of how much money is involved. :)
    Getting Host-C to admit their own mistakes, and getting LET to recognize Host-C's mistakes — it is truly an uphill battle. :(

    @JasonJohn said: In fact, the amount involved in this dispute is very small. My reason for posting on LET is not about the money itself, but rather about what I believe to be Host-C's incorrect method of calculating the remaining value in their billing system, and the fact that they have persistently refused to acknowledge the error when I pointed it out. Many other users who are also due refunds will likewise be affected by what I believe to be this incorrect calculation. Business transactions should be conducted with integrity — neither more nor less, but exactly the right amount.

    At the same time, I would like this thread to remain open, or alternatively, Host-C commits to handling refunds for users affected by this EOL and any future refund cases in accordance with the requirements I have put forward.

    You have also overlooked the PayPal transaction fees.

  • I would like to talk about llamas.

  • rpqurpqu Member

    @AlteredParadox said:
    I would like to talk about llamas.

    Okay, specifically on what?

  • edited May 3

    @JasonJohn said:
    getting LET to recognize Host-C's mistakes

    OK, i am recognize. Is this sufficient for you? I mean, i don't want to rush you or anything but as you see there is an important discussion regarding llamas about to happen and people's schedules are a little tight.

    Thanked by 1host_c
  • jsgjsg Member, Resident Benchmarker

    @AlteredParadox said:
    I would like to talk about llamas.

    The Lama fish variety? And, YES, let's have a scholarly discussion on Lamas!

    Thanked by 1AlteredParadox
  • ascicodeascicode Member

    Thanked by 1AlteredParadox
  • @jsg said:

    @AlteredParadox said:
    I would like to talk about llamas.

    The Lama fish variety? And, YES, let's have a scholarly discussion on Lamas!

    Thanked by 4rpqu oloke ariq01 jsg
  • rpqurpqu Member

    @AlteredParadox said:

    @jsg said:

    @AlteredParadox said:
    I would like to talk about llamas.

    The Lama fish variety? And, YES, let's have a scholarly discussion on Lamas!

    Looks like chimera storage server

    Thanked by 1ariq01
  • host_chost_c Patron Provider, Top Host, Megathread Squad

    @AlteredParadox said:
    I would like to talk about llamas.

    Key Llama Facts

    • "Humming" Language: Llamas communicate with each other by making a soft humming noise, which changes tone to express curiosity, worry, or comfort.

    • Intelligent Protest: If a llama is overloaded with too much weight, it will simply refuse to move, lie down, or hiss and spit until the weight is reduced.

    • Excellent Guardians: Because they are protective and social, llamas are frequently used to guard herds of sheep or goats from predators.

    • Spitting Hierarchy: While they generally only spit at humans if threatened, llamas spit at each other to establish pecking order, often shooting green, undigested food up to 10–15 feet. ( sniper elite )

    • Efficient Pack Animals: Domesticated 4,000–5,000 years ago in the Andes, they can carry about 25–30% of their body weight for 10–12 miles. ( might be handy as current fuel prices are insane )

    • Friendly Fibers: Llama wool is light, warm, and water-repellent.

    Hmm, makes me want to get one and replace a minion....... :D :D

    Thanked by 3AlteredParadox rpqu jsg
  • @host_c said:

    @AlteredParadox said:
    I would like to talk about llamas.

    Key Llama Facts

    • "Humming" Language: Llamas communicate with each other by making a soft humming noise, which changes tone to express curiosity, worry, or comfort.

    • Intelligent Protest: If a llama is overloaded with too much weight, it will simply refuse to move, lie down, or hiss and spit until the weight is reduced.

    • Excellent Guardians: Because they are protective and social, llamas are frequently used to guard herds of sheep or goats from predators.

    • Spitting Hierarchy: While they generally only spit at humans if threatened, llamas spit at each other to establish pecking order, often shooting green, undigested food up to 10–15 feet. ( sniper elite )

    • Efficient Pack Animals: Domesticated 4,000–5,000 years ago in the Andes, they can carry about 25–30% of their body weight for 10–12 miles. ( might be handy as current fuel prices are insane )

    • Friendly Fibers: Llama wool is light, warm, and water-repellent.

    Hmm, makes me want to get one and replace a minion....... :D :D

    Each minion needs a guard llama.

    Thanked by 1oloke
  • host_chost_c Patron Provider, Top Host, Megathread Squad

    @AlteredParadox said: Each minion needs a guard llama.

    Hmm, I need to move the office to the zoo in that case....... wait, the zoo has lions and tigers also, don't those eat lamas and minions?..... not a good idea, need to process this a bit longer......

    :D :D

  • SaragoldfarbSaragoldfarb Member, Megathread Squad

    Hi. What's up?

    Thanked by 2ariq01 tfgp99
  • @Saragoldfarb said:
    Hi. What's up?

    Llamas

  • JasonJohnJasonJohn Member
    edited May 4
    • Thanks to Claude for generating the table — readability has improved significantly.

    Refund Dispute Summary

    Item Value
    Service retired 2026-04-30
    Both servers $45/year

    Server I185

    Item Value
    Paid $45.00
    Billing period 2025-06-04 → 2026-06-03 (365 days)
    Remaining days 34 days (May 1 → Jun 3, counted from May 1)
    Refund formula (34/365) × $45.00 = $4.19
    Received $3.59 ✗

    The Error

    Host-C calculated one day short, and also did not account for the PayPal transaction fees.

    Calculation Amount PayPal fee
    Host-C's (wrong): (33/365) × $45 $4.07 $0.48
    Correct (gross): ((34/365) × $45 + $0.3) / 0.956 $4.70 $0.51
    Shortfall $1.11 ($0.51 PayPal fee)

    Server I125

    Item Value
    Pre-existing credit $11.96
    Pre-existing remaining days 78 days (2025-07-10 → 2025-09-25)
    New payment $32.42
    Billing period 2025-09-26 → 2026-06-03 (251 days)
    Remaining days 34 days (May 1 → Jun 3, counted from May 1)
    Refund formula (34/251) × $32.42 = $4.39
    Received $2.90 ✗

    The Error

    Host-C prorated on $32.42 only, ignoring the $11.96 credit.

    Calculation Amount PayPal fee
    Host-C's (wrong): (34/(78+251)) × $32.42 $3.35 $0.45
    Correct (gross): ((34/251) × $32.42 + $0.3) / 0.956 $4.91 $0.52
    Shortfall $2.01 ($0.52 PayPal fee)

    Summary

    Server Correct (gross) PayPal fee Received
    Server I185 $4.70 $0.51 $3.59 ✗
    Server I125 $4.91 $0.52 $2.90 ✗
    Total $9.61 $1.03 $6.49 ✗
    Shortfall $3.12 ($1.03 PayPal fee)

    Dispute Basis

    The $11.96 pre-existing credit was applied toward Server I125's period from July 10, 2025 to September 25, 2025, and the $32.42 bill corresponds to Server I125's period from September 26, 2025 to June 3, 2026. In Host-C's calculation formula, the input amount ($32.42) is correct, but the number of days used to calculate the daily rate is incorrect.



    Reproducible calculation

    Reproducible Calculation

    Server I185

    Billing days  : 365  (2025-06-04 → 2026-06-03, inclusive)
    Remaining days: 34   (2026-05-01 → 2026-06-03, inclusive)
    Service price : $45.00
    PayPal rate   : 4.4% + $0.30 flat fee  →  divide gross by 0.956, then subtract $0.30
    
    Raw refund         = (34 / 365) × 45.00          = $4.1918...  ≈ $4.19
    Gross (with fee)   = (4.19 + 0.30) / 0.956       = $4.6966...  ≈ $4.70
    PayPal fee         = 4.70 × 0.044 + 0.30         = $0.507      ≈ $0.51
    Net received       = 4.70 − 0.51                  = $4.19  ✓
    

    Server I125

    New-payment period : 251 days  (2025-09-26 → 2026-06-03, inclusive)
    Remaining days     : 34        (2026-05-01 → 2026-06-03, inclusive)
    New payment        : $32.42    (covers 2025-09-26 → 2026-06-03 only)
    Pre-existing credit: $11.96    (covers 2025-07-10 → 2025-09-25; separate billing segment)
    
    Raw refund         = (34 / 251) × 32.42           = $4.3923...  ≈ $4.39
    Gross (with fee)   = (4.39 + 0.30) / 0.956        = $4.9079...  ≈ $4.91
    PayPal fee         = 4.91 × 0.044 + 0.30          = $0.516      ≈ $0.52
    Net received       = 4.91 − 0.52                  = $4.39  ✓
    

    Total

    Total gross        = 4.70 + 4.91                  = $9.61
    Total PayPal fee   = 0.51 + 0.52                  = $1.03
    Total net          = 4.19 + 4.39                  = $8.58
    Actually received  = 3.59 + 2.90                  = $6.49
    Shortfall          = 9.61 − 6.49                  = $3.12  (including $1.03 PayPal fees)
    


    The script to avoid this edge case

    Script: Avoid This Edge Case

    from datetime import date
    
    PAYPAL_RATE = 0.044
    PAYPAL_FLAT = 0.30
    
    def count_days_inclusive(start: date, end: date) -> int:
        """Count calendar days inclusive of both endpoints."""
        return (end - start).days + 1
    
    def gross_payout(net_refund: float) -> float:
        """
        Compute the gross amount Host-C must send so that after PayPal deducts
        fee = gross * 4.4% + $0.30, the recipient receives exactly net_refund.
    
        Formula: gross = (net_refund + 0.30) / (1 - 0.044)
        """
        return (net_refund + PAYPAL_FLAT) / (1 - PAYPAL_RATE)
    
    def paypal_fee(gross: float) -> float:
        return round(gross * PAYPAL_RATE + PAYPAL_FLAT, 2)
    
    def compute_refund(service_price: float,
                       billing_start: date,
                       billing_end: date,
                       eol_date: date,
                       service_retired: date) -> dict:
        """
        Compute the correct refund for a single service.
    
        Parameters
        ----------
        service_price   : amount paid for the billing period
        billing_start   : first day of the paid billing period (inclusive)
        billing_end     : last day of the paid billing period (inclusive)
        eol_date        : last day service was available (inclusive)
        service_retired : day after eol_date; refund starts here
    
        Edge cases handled
        ------------------
        - remaining_start is always service_retired (the day AFTER eol_date),
          ensuring the eol day itself is NOT double-counted.
        - Both billing_end and remaining_end are inclusive, so we add 1 to
          (end - start).days for both total and remaining spans.
        - If service_retired > billing_end, remaining_days = 0 → no refund.
        """
        total_days     = count_days_inclusive(billing_start, billing_end)
        remaining_start = service_retired          # first day after EOL
        remaining_end   = billing_end
        remaining_days  = max(0, count_days_inclusive(remaining_start, remaining_end))
    
        daily_rate  = service_price / total_days
        net_refund  = round(daily_rate * remaining_days, 2)
        gross       = round(gross_payout(net_refund), 2)
        fee         = paypal_fee(gross)
    
        return {
            "total_days":      total_days,
            "remaining_days":  remaining_days,
            "daily_rate":      round(daily_rate, 6),
            "net_refund":      net_refund,
            "gross_payout":    gross,
            "paypal_fee":      fee,
        }
    
    
    if __name__ == "__main__":
        # --- Server I185 ---
        i185 = compute_refund(
            service_price  = 45.00,
            billing_start  = date(2025, 6,  4),
            billing_end    = date(2026, 6,  3),
            eol_date       = date(2026, 4, 30),
            service_retired= date(2026, 5,  1),
        )
        print("Server I185:", i185)
    
        # --- Server I125 ---
        # Only the $32.42 new-payment segment is relevant for the refund.
        # The $11.96 pre-existing credit covered 2025-07-10 → 2025-09-25
        # and is a separate billing segment; it is NOT included in service_price
        # here because its period ends before the refund window begins.
        i125 = compute_refund(
            service_price  = 32.42,
            billing_start  = date(2025, 9, 26),
            billing_end    = date(2026, 6,  3),
            eol_date       = date(2026, 4, 30),
            service_retired= date(2026, 5,  1),
        )
        print("Server I125:", i125)
    
        total_gross = i185["gross_payout"] + i125["gross_payout"]
        total_fee   = i185["paypal_fee"]   + i125["paypal_fee"]
        print(f"\nTotal gross to send : ${total_gross:.2f}")
        print(f"Total PayPal fee    : ${total_fee:.2f}")
        print(f"Total net received  : ${i185['net_refund'] + i125['net_refund']:.2f}")
    

    Expected output

    Server I185: {'total_days': 365, 'remaining_days': 34, 'daily_rate': 0.123288,
                  'net_refund': 4.19, 'gross_payout': 4.70, 'paypal_fee': 0.51}
    Server I125: {'total_days': 251, 'remaining_days': 34, 'daily_rate': 0.129163,
                  'net_refund': 4.39, 'gross_payout': 4.91, 'paypal_fee': 0.52}
    
    Total gross to send : $9.61
    Total PayPal fee    : $1.03
    Total net received  : $8.58
    

    @host_c Please reply. Even the adorable llama doesn't want anyone to make mistakes.

  • JohnnySacJohnnySac Member

    That $3.12 is coming out of Stuart's paycheck.

    Thanked by 1host_c
  • Thanked by 3ariq01 host_c jsg
Sign In or Register to comment.