SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Addict
    Join Date
    Sep 2011
    Posts
    266
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Managing Credits In Different Currencies

    Hi, my site allows users (buyers) to buy e-learning courses for other users (receivers).

    The courses are different prices and are in a mix of different currencies such as USD, EUR, AUD and users pay for them with paypal.

    If the receiver does not start the course within 28 days the the buyer gets a refund back but paypal does not like issuing all of these refunds, so i am thinking of changing my system to a credit system instead of a refund.

    For example, if the buyer buys a $10 course and it is not started, the buyers site account is credited $10.

    My worry is, how can i manage the currency conversion etc. As the site takes the initial payment of $10, then credits the buyers site account with $10, but what if the buyer then wants to buy a 7 course for another user and that gets refunded and so on and so on... how can i manage the currencies and credits as exchange rates need to be managed but a user is only paying with credits the second time around... thanks in advance for your help.

  2. #2
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Is there a reason why you do not charge the buyer until the course is actually started?

  3. #3
    SitePoint Addict
    Join Date
    Sep 2011
    Posts
    266
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The buyer is charged immediately when the buy the course...

  4. #4
    SitePoint Addict kduv's Avatar
    Join Date
    May 2012
    Location
    Maui, HI
    Posts
    211
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Since exchange rates change frequently, you'll need to pull the current rates from an external API. There are a bunch out there. Some are free some are not. Some require registration. Some have a very limited amount of currencies. Some API's are a pain to implement.

    Here's a very simple script I just wrote using an API that's free, requires no registration, has a simple JSON output, and updates the exchange rates every two minutes.

    It's a real quick and dirty implementation, but you'll get the idea. You may want to implement it in a more portable class or something.

    PHP Code:
    <?php

    // Function to retrieve the value (if set) of a GET variable, or return a default
    function getVar($var$default null)
    {
        if ((isset(
    $_GET[$var])) && ($_GET[$var] != '')) {
            return 
    trim($_GET[$var]);
        }
        
        return 
    $default;
    }

    $from_amt     getVar('amt'1);
    $from         strtoupper(getVar('from''USD'));
    $to         strtoupper(getVar('to''EUR'));
    $api_url 'http://www.getexchangerates.com/api/latest.json';

    // Make sure $from_amt is a number
    if (!is_numeric($from_amt)) {
        exit(
    "The amount you are converting from must be a valid numeric value.");
    }

    // Grab the JSON from the converter API
    $api_feed file_get_contents($api_url);
    if (
    $api_feed === false) {
        exit(
    "There was an error pulling the data from {$api_url}");
    }

    // Convert the JSON to an easy-to-use array
    $exchange_rates json_decode($api_feedtrue);
    if (
    $exchange_rates == null) {
        exit(
    "Unable to decode JSON feed from API");
    }
    $exchange_rates $exchange_rates[0];

    // Make sure $from is a supported/valid currency
    if (!array_key_exists($from$exchange_rates)) {
        exit(
    "\"{$from}\" is either NOT a supported exchange rate, or it is an invalid one.");
    }

    // Make sure $to is a supported/valid currency
    if (!array_key_exists($to$exchange_rates)) {
        exit(
    "\"{$to}\" is either NOT a supported exchange rate, or it is an invalid one.");
    }

    // The API used in this example uses USD as it's base line.
    // If $from is not USD, we'll need to first convert it to USD
    // before we can convert it to $to.
    $usd_amt = ($from != 'USD') ? $from_amt $exchange_rates[$from] : $from_amt;

    // Convert it
    $new_amt $usd_amt $exchange_rates[$to];

    echo 
    "{$from} {$from_amt} = {$to} {$new_amt}<br><br>";
    echo 
    "Exchange Rate data was last updated on: " date('Y-m-d H:i:s T'$exchange_rates['DateTime']);

    ?>
    Keith
    Freelance web developer
    http://www.duvalltech.com/

  5. #5
    SitePoint Addict kduv's Avatar
    Join Date
    May 2012
    Location
    Maui, HI
    Posts
    211
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    I threw together a class for that API ... just because. Suggestions and feedback are welcome.
    PHP Code:
    /*************************************************************************
     A PHP class to convert currencies using the free exchange rate API
     at http://www.getexchangerates.com/
     
     Created by Keith Duvall (http://www.duvalltech.com/
     Copyright (C) Oct 2012
     
     You may freely use, modify, and share this however you like -- personal or 
     commercial -- as long as you don't charge to distribute it. 
     
     Please give credit where credit is due.
    *************************************************************************/
    class CurrencyExchange
    {
        
    // API info
        
    protected $api_url 'http://www.getexchangerates.com/api/latest.json';
        protected 
    $feed_expires true;
        protected 
    $expires_in 120// Seconds
        
    protected $base_currency 'USD'// Currency the feed is based on
        
        // Defaults
        
    protected $from_currency 'USD';
        protected 
    $to_currency 'EUR';
        
        
    // Don't edit these
        
    protected $last_update null;
        protected 
    $exchange_rates = array();
        
        public function 
    __construct()
        {
            
    $this->refreshFeed();
        }
        
        protected function 
    throwEx($msg "Unknown")
        {
            throw new 
    Exception($msg);
        }
        
        
    /**
        * Returns the time since the API feed was last updated.
        * 
        * Valid arguments are:
        * minutes: Minutes since it was last updated.
        * seconds: seconds since it was last updated.
        * absolute: absolute update time in the form of a unix EPOCH timestamp
        */
        
    public function lastUpdate($format 'absolute')
        {
            switch (
    $format)
            {
                case 
    "minutes":
                    return (
    time() - $this->last_update) / 60;
                    break;
                case 
    "seconds":
                    return 
    time() - $this->last_update;
                    break;
                default:
                    return 
    $this->last_update;
                    break;
            }
        }
        
        
    /**
        * Tells you whether the feed has expired based on $this->expires_in
        */
        
    public function feedExpired()
        {
            if ((
    time() - $this->last_update) >= $this->expires_in) { return true; }
            return 
    false;
        }
            
        
    /**
        * Returns an array of all the conversion rates
        */
        
    public function listRates()
        {
            return 
    $this->exchange_rates;
        }
        
        
    /**
        * Converts $amount from $from currency to $to currency and returns the new amount as a float.
        * If $from or $to are null, it will use the class properties above.
        */
        
    public function convert($amount$from null$to null)
        {
            
    $from = ($from == null) ? strtoupper($this->from_currency) : strtoupper($from);
            
    $to = ($to == null) ? strtoupper($this->to_currency) : strtoupper($to);
            
            if (!
    is_numeric($amount)) {
                
    $this->throwEx("The amount to convert must be numeric.");
            }
            
            
    // Make sure the exchange rates have been pulled and the feed is current
            
    if ($this->last_update == null) { $this->refreshFeed(); }
            if (
    $this->feed_expires && $this->feedExpired()) { $this->refreshFeed(); }
            
            
    // Make sure $from and $to is valid and supported by the API
            
    if (!array_key_exists($from$this->exchange_rates)) {
                
    $this->throwEx("Invalid or unsupported currency: {$from}");
            }
            if (!
    array_key_exists($to$this->exchange_rates)) {
                
    $this->throwEx("Invalid or unsupported currency: {$to}");
            }
            
            
    // Convert the amount given to the base currency
            
    $base_amount = ($from != strtoupper($this->base_currency)) ? $amount $this->exchange_rates[$from] : $amount;
            
            
    // Convert to new currency
            
    $new_amount $base_amount $this->exchange_rates[$to];
            
            return 
    $new_amount;
        }
        
        
    /**
        * Pulls the JSON data from the API and converts the rates
        * into a more usable array.
        */
        
    public function refreshFeed()
        {
            if (!
    $raw_data file_get_contents($this->api_url)) { 
                
    $this->throwEx("There was an error pulling the feed from the API."); 
            }
            
            if (!
    $data json_decode($raw_datatrue)) { 
                
    $this->throwEx("The feed API returned invalid JSON data."); 
            }
            
            
    $data $data[0]; // Strip outer layer
            
            
    $this->last_update $data['DateTime'];
            unset(
    $data['DateTime']);
            
            
    $this->exchange_rates $data;
            unset(
    $data$raw_data);
        }


    Keith
    Freelance web developer
    http://www.duvalltech.com/

  6. #6
    SitePoint Addict
    Join Date
    Sep 2011
    Posts
    266
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Excellent, thanks a million for this...


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •