Different payment details in a common list, to be casted
I'm not in love with having an enum to know what base type to cast to.  If you want to stick to it then I'll give you a couple of pointers then later I'll give you a couple more options to think about

Make the base abstract and make the enum abstract

public abstract class PaymentDetailBase
{
    protected PaymentDetailBase(string id)
    {
        this.Id = id;
    }

    public string Id { get; }

    public abstract PaymentMethodEnum PaymentMethod { get; }
}


if you are going to cast based on the Enum then you don't want it being sent in the constructor.  What if I sent in the wrong enum for the type

Now classes the inherit from the base will be forced to fill in the type

public class CardDetail : PaymentDetailBase
{
    public CardDetail(string id, string last4, DateTime expiry, PaymentCardTypeEnum cardType) : base(id)
    {
        this.Last4 = last4;
        this.Expiry = expiry;
        this.CardType = cardType;
    }

    public string Last4 { get; }

    public DateTime Expiry { get; }

    public PaymentCardTypeEnum CardType { get; }

    public override PaymentMethodEnum PaymentMethod =&gt; PaymentMethodEnum.CreditCard;
}


I've worked with applications like this and I don't really care for the Enum.  It violates the open/close principle.  If I want another payment type I need to change the enum and some switch code that does hardcoded cast (yuck).   And what are you saving?  A switch statement instead of getting the base class and doing the AS statement and checking for null?  

Really when you run into this situation you need to think about your design.  What in the outside needs to know about those extended properties.  If everything then why cast to the base object in the first place just pass in the right class or you can try to make use of generics with constraints.  

Another option is if not a lot needs to know about the specific class then have the class do the operation you want done.  For Example you need to just copy over those properties to an entity.  Then aleave the base class abstract and make an abstract method like 

public void UpdateEntity(PaymentEntity entity);


now each class need to implement the update entity and it knows about it's own properties.